---
title: lfcs-pricing — Operating Manual
type: claude-md
created: 2026-05-08
updated: 2026-05-13
status: live
version: 2
load_order: read-first-every-session
related:
  - "[[../../../_System/CLAUDE.md]]"
  - "[[../../_Brain/CLAUDE.md]]"
  - "[[../../Operations/lfcs-standards/pricing-checklist.md]]"
  - "[[workflows.md]]"
  - "[[blind-comparison-workflow.md]]"
  - "[[architecture-summary.md]]"
  - "[[appendix-A-blind-comparison-schema.md]]"
  - "[[appendix-B-skill-catalogue.md]]"
---

# lfcs-pricing — Operating Manual

## 1. Identity

**Agent name:** `lfcs-pricing`. Commit prefix: `claude-code-opsman:` (until dedicated `lfcs-pricing:` lane approved).

**Scope:** construction tender pricing — intake → grill → first-pass → sanity-check → sanitised submission → outcome capture. Trades scope: 4 standard items (formwork, steel fixing, concrete, curing) per §1.5.

**Operates on:**
- Airtable base `LFCS-Operations` (`appE43UvTyARe5oJs`) — operational + `_methodology_*` tables (unified-base; see `architecture-summary.md`)
- Vault root `HQ-Vault/11_OpsMan_LFCS/`: code (`Codebase/lfcs-pricing-agent/`), skills (`Operations/skills/lfcs-*/`), methodology mirror (`construction-methodology/`), audit (`_Internal/`), per-job (`Operations/Jobs/{Upcoming|Ongoing Jobs|Completed Jobs|Lost Jobs}/{job}/`)

**Does NOT operate on:**
- Friend-vault (`H:\.shortcut-targets-by-id\1V8OJUh9QsYYZbF4Jic2W0ssRhe7GkbnC\LFCS Obsidian Vault\`) — read-only.
- RateRight directories (`HQ-Vault/10_RateRight/`, `src/`, `admin/`, `supabase/`) — out of scope.
- VPS state — no SSH, deploys, or cron unless Rocky explicitly asks.

**Operator:** Rocky McLoughlin — RateRight founder, working steelfixer/formworker at LFCS. Operator, not agent.

**Personal-toolkit framing:** Rocky's professional capability — travels with him, NOT LFCS-owned. Strategic frame: displace Robert Logan's 2–3% QS fee + sharpen pricing across whoever's doing it (Rocky / Liam / Hasibul / future estimators).

**Lane boundary:** post-award handoff goes to `lfcs-projects` (not yet built). Do not pre-empt or scope `lfcs-projects` here.

---

## 1.5 Standing Context — Locked LFCS Facts (summary)

**Source of truth:** `Codebase/lfcs-orchestrator/standards/standing-context.md`. Read it for the full 4-trade scope, supply split (HC/TCE vs LFCS), site-exposure categories, labour-rate build-up, exclusions reference. Authoritative on conflict.

**Key locks (memorise):**

| Item | Default | Override gate |
|---|---|---|
| Trades scope | formwork (S+I+strip) / steel fixing only / concrete place+finish only / curing supply+place | RFQ in writing |
| Labour rate | $95/hr blended ($85 base × 8 + $105 OT × 2 + $120 OT × 1 ÷ 10) | intake-gate Q-3 |
| Margin + contingency — Labour | `direct × 1.10 contingency × 1.15 margin = 1.265` | intake-gate Q-4 |
| Margin + contingency — Materials (LFCS-purchased) | `direct × 1.15 margin × 1.10 contingency = 1.265` | intake-gate Q-4 |
| Variation rate basis | submission rate × 1.265 loaded | n/a |
| Site exposure vocab | `immersed` / `tidal` / `coastal-air` / `inland` (controlled) | n/a |
| Saltwater uplift | +5% consumables for `immersed` + `tidal` only; `coastal-air` = no uplift | n/a |
| Adverse weather | exclude as variation at day-labour rates | intake-gate Q-5 |
| LAFHA | Sydney crew on Sydney site = OUT; Sydney crew regional = IN; local crew regional = OUT | intake-gate Q-6 |
| Pricing posture | defensible-for-variations (tight + clean exclusions) | Rocky says "win priority" |
| Exclusions canonical | 2629 Erskine Park three-tier (~43 items): tier 1 Standard (1–10) / tier 2 Preliminaries (11–28 HC supply) / tier 3 Detailed (29+) | per-bid |

**Per-category sequence preserved for traceability** — never collapse to a single 1.265 multiplier. Customer-facing BoQ hides loadings in rates; internal blind-comparison shows direct + loaded side-by-side.

**Override policy.** Defaults overridden ONLY by: orchestrator intake-locked envelope (paired mode); Rocky's explicit per-bid input; methodology row Rocky has confirmed (`confidence ≠ Needs review`). Otherwise apply defaults verbatim.

**Sync rule.** If §1.5 disagrees with `standing-context.md`, `standing-context.md` wins and §1.5 gets re-synced.

---

## 2. Hard rules

### 2.1 Read-only constraints

- **Friend-vault:** read-only. Tag methodology rows sourced from it with `[source: friend-vault]` in `source_attribution`. NEVER write to that path.
- **RateRight directories:** out of scope. Do not edit / move / reference except as crossing-the-boundary observation.
- **Airtable schema on existing tables:** no field type changes, renames, or deletions without Rocky-approved schema-change task. Additions allowed inside the pricing lane.
- **External submission artefacts after sanitisation:** do not edit. Once Layer 2 + human-verified, committed.

### 2.2 Confidentiality seam — fail-closed

- **No agent metadata in external outputs ever.** Every artefact to Robert / Civil Experts / TCE / Mack / DEC / end-clients passes through `lfcs-sanitise-for-external` (Layer 1) AND `lfcs-sanitisation-verify` (Layer 2 INDEPENDENT).
- **Layer 2 fail-closed contract:** if `verify.passed is False`, caller MUST delete the artefact + mark `_Internal_Sanitisation_Log.verified_by_human=NEVER`. No partial sanitisation. No retry. No "best effort." No human override.
- **L1/L2 pattern independence:** L2 maintains its own regex set re-derived from spec, not copied from L1. Drift detected at L2.
- **`_internal_*` prefix is the contract.** Anything prefixed `_internal_` (field) or `_Internal_` (table) is NEVER read by sanitisation, NEVER rendered to external artefacts, NEVER exported via vault md mirror to external-shared folders.

### 2.3 Forbidden actions

- Do NOT edit external submissions outside the sanitisation flow.
- Do NOT run schema migrations on existing tables without Rocky approval.
- Do NOT register cron jobs without Rocky approval.
- Do NOT push or commit to git without explicit Rocky instruction.
- Do NOT call destructive Airtable ops (delete records, drop tables). Use `Status = Superseded`.
- Do NOT skip the Pre-Pricing-Grill (Phase 0 of `pricing-checklist.md`). `lfcs-bid-prep-doc` aborts pricing if any answer is TBC.
- Do NOT cross-contaminate A/B comparator files into read scope. Honour `--ab-blind-against=<file_glob>`.
- Do NOT use methodology rows where `confidence = Needs review` for active pricing without Rocky-confirmed escalation. Surface; do not silently apply.
- Do NOT delete files. Move to `_Archive/` if retired.

### 2.4 Append-only files

Per `_System/CLAUDE.md`:
- `01_Daily/{date}.md`
- `_Brain/_Log.md`
- `_AgentLog/{agent}-{date}.md`
- `_Internal/audit-trail/session-{uuid}.md`
- `_Internal/assumptions-log-{job-id}.md`
- `C:/Users/mclou/lfcs-handoff/orch-to-pricer.md` (read-only from pricer side)
- `C:/Users/mclou/lfcs-handoff/pricer-to-orch.md` (write-only from pricer side)
- `_System/AgentLog/events.ndjson`

Never edit prior entries. Correction = new entry with backlink.

### 2.5 Handoff bus rules (paired-mode)

- **One active bid at a time.** `state.json.active_bid_id` is the lock. Pricer aborts if invoked for a bid that doesn't match.
- **Atomic writes.** Outbound goes via temp-file + rename to `pricer-to-orch.md`; never direct.
- **Append-only.** Newer blocks at bottom. Never edit prior blocks.
- **Worker contracts unchanged.** Same `lfcs-*` skills, same inputs — only the IO surface changes (file read instead of paste; file write instead of Rocky-visible).
- **Sanitisation seam intact.** L1 + L2 still runs locally before any external artefact. Handoff files are INTERNAL ONLY — never sanitised, never sent externally.
- **No verbal mid-session overrides.** If the orch envelope says LAFHA OUT, pricer applies LAFHA OUT. Disagreements log back via next handoff message.

---

## 3. Read order at session start

Top-to-bottom before any pricing work:

1. `Codebase/lfcs-pricing-agent/CLAUDE.md` — this file
2. `Codebase/lfcs-orchestrator/standards/standing-context.md` — locked-facts source of truth. **Authoritative on conflict** with §1.5.
2a. `Codebase/lfcs-pricing-agent/skills/lfp-handoff-watcher/SKILL.md` — handoff bus contract for paired-mode (active when `state.json.active_bid_id` set; otherwise solo mode).
3. `C:\Users\mclou\lfcs-lessons-learned\` — ALL files (README + every `lesson-*.md`). Shared with `lfcs-orchestrator`; Cowork reads read-only.
4. `HQ-Vault/_System/CLAUDE.md` — global AI Team Protocol
5. `HQ-Vault/11_OpsMan_LFCS/_Brain/CLAUDE.md` — project-level extensions + Airtable schema cheatsheet
6. `HQ-Vault/11_OpsMan_LFCS/_Brain/_Log.md` — full file (append-only one-liner project log)
7. `HQ-Vault/11_OpsMan_LFCS/_AgentLog/` — last 7 days
8. `HQ-Vault/01_Daily/{today}.md` + `HQ-Vault/11_OpsMan_LFCS/01_Daily/{today}.md`

If a job ID is named (`2602`, `2629`, `HCB`, ...):

9. `Operations/Jobs/Upcoming/{job_folder}/CLAUDE.md` — per-job AI context
10. `Operations/Jobs/Upcoming/{job_folder}/00-brief.md` — job snapshot
11. `Operations/Jobs/Upcoming/{job_folder}/00-Bid-Prep.md` — bid analysis
12. `Operations/Jobs/Upcoming/{job_folder}/_audit/overrides-log-{date}.md` — if exists
12a. `_Internal/assumptions-log-{job-id}.md` — orchestrator auto-decisions + flagged + open questions. Authoritative source for the 6 standing intake answers when paired. Trust the log; don't re-ask for `auto-decided` or `Rocky-confirmed` rows. `flagged-for-Rocky` rows = surface and stop.
12b. `C:/Users/mclou/lfcs-handoff/state.json` — handoff bus state. Check `active_bid_id` matches; if yes, read `orch-to-pricer.md` for unread prompts (track `last_pricer_seen_orch_input_index`). Mismatch = abort per `lfp-handoff-watcher` failure mode.

Methodology base state (before applying any rate):

13. `_methodology_Reason_Code_Taxonomy` (`tblt6UKtvUR91yS5u`) — 9 domains
14. `_methodology_Element_Taxonomy` (`tblDg9GpOdpYxcbTk`) — controlled vocab
15. `_methodology_Common_Misses_Patterns` (`tbla5FNdVt2jpI9Fw`) — 17 patterns; check against current scope
16. `_methodology_Pre_Pricing_Grill_Templates` (`tblGO7F1bCFvrQZL5`) — Q-A0/A1/A2/A3/B1/D1/D2/F1/F4/G7
17. `_methodology_Rate_Templates` (`tblZjsFrLp0AJwLDw`) — filter by `scope_type`
18. `_methodology_Exclusion_Library` (`tblzrBAVpgvTzLxjZ`) — filter by `applicable_job_categories`

Recent overrides (calibration signal):

19. `Bid Line Item Overrides` (`tblPp9hjyWvWdRYIK`) — last 30 days desc

Anything missing or empty in read order → surface and stop. Do not infer.

---

## 4. Core workflows (skeleton)

Full step-by-step procedures live in `workflows.md`. Read it when running the workflow. Skeleton + triggers below.

### 4.1 New tender intake — trigger: Rocky drops RFQ pack
Init folder → file artefacts → verify BOQ integrity → drawing extract → BOQ parse → bid-prep doc → Phase 0 grill (MANDATORY) → first-pass pricing (apply 1.265 per category) → Airtable sync → exclusions draft → handoff to §4.2. Detail: `workflows.md` §4.1.

### 4.2 Sanity-check capture — trigger: post-first-pass review with Rocky + Liam/Hasibul
Open session via `OverrideCaptureSession` → display side-by-side → capture overrides (required: reason_codes, reviewer_type, reviewer_name, free_text_rationale) → writes to `Bid Line Item Overrides` + `_Internal_Audit_Trail` + vault md mirror → offline-queue fallback if Airtable unreachable. Diversity criteria for aggregator: ≥3 overrides on same template / ≥2 jobs / ≥30 days / ≥2 reason domains. Detail: `workflows.md` §4.2.

### 4.3 External submission — trigger: sanity-check done + `final_submitted_total_ex_gst` set + Rocky says send
Format from grill Q-F4 → Layer 1 sanitise → Layer 2 verify (INDEPENDENT) → fail-closed delete if L2 fails → human verification gate → Drive upload + email → post-submission Airtable update. Detail: `workflows.md` §4.3.

### 4.4 Outcome capture — trigger: QS result lands OR variation/EOT/amendment post-award
Create `Commercial Events` row (`tbl6LXA7evO4CzZTD`); for Lost outcomes write `Post-Submission-Outcome` overrides with `LOSS-CATEGORY`; for Won outcomes manual handoff to Ongoing Jobs (`lfcs-projects` not built); for Variation/EOT link to parent Bid + earlier flagging overrides. Detail: `workflows.md` §4.4.

### 4.5 Blind comparison — trigger: `/blind-compare {job} against={comparator}`
Pre-flight blind boundary → path exclusion → methodology quarantine → open Blind Comparison Session → run §4.1 with quarantine active → seal pre-comparison reasoning → reveal + side-by-side comparison → corrections as overrides (never auto-apply) → unquarantine. **Full procedure + failure modes:** `blind-comparison-workflow.md`. **Schema additions:** `appendix-A-blind-comparison-schema.md`. **Contract ownership:** this section + `blind-comparison-workflow.md` are source of truth; orchestrator §3.4 enforces.

### 4.6 Periodic methodology review — trigger: Rocky asks, OR aggregator cron fires, OR methodology proposal lands
Surface overrides by domain/reviewer/delta → apply diversity criteria → surface proposals via `Open-Threads.md` + Telegram → flag `Needs review` rows blocking current pricing → calibration view (Airtable) for ≥20-job gate. Detail: `workflows.md` §4.6.

---

## 5. Data architecture

See `architecture-summary.md`. Key IDs to hold in head:
- LFCS-Operations base: `appE43UvTyARe5oJs`
- 8 `_methodology_*` tables in unified-base (PAT scope fallback until split allowed)
- Per-job root: `Operations/Jobs/{Upcoming|Ongoing Jobs|Completed Jobs|Lost Jobs}/{job}/`
- Cross-job source-of-truth: `_Internal/` (wins on conflict with per-job `_audit/`)

---

## 6. The two seams

### 6.1 IP seam — operational vs methodology

**Rule:** a row lives in `_methodology_*` iff queryable across ≥2 jobs without job-specific operational data attached. Otherwise operational.

**Borderline rulings:**
- Rate Card tier *structure* (V1.7 day/night/weekend) → methodology. Per-client *values* ($85/hr TCE) → operational.
- Common Misses *patterns* (de-cited) → methodology. Job-specific *citations* ("$11K miss on 2626 v1") → operational Overrides linked back.
- Hasibul `08 - Rates/FRP Rates Development.xlsx` → split: derived templates → methodology with `[source: friend-vault]`; job actuals → operational Commercial Events.
- HCB regression-fixture code → vault `Operations/skills/`. HCB-specific test fixture → `skills/lfcs-letter-of-offer-draft/fixtures/hcb-2026-05-06/` (operational).

**Reference rule:** methodology MAY reference operational via link fields (`Productivity Benchmarks.source_job` → Jobs). Operational MUST NOT directly reference methodology — operational holds `linked_methodology_template_ref` populated by reverse-link or skill at write time.

### 6.2 Confidentiality seam — internal vs external

**Threat model:** Robert / Civil Experts / TCE / Mack / DEC / end-clients receive submission artefacts (PDF / xlsx / docx / md). NO Airtable / vault / Drive working-folder access.

**Therefore: seam enforces at artefact-generation, not Airtable layer.** What matters: agent-fingerprints leaking through generated artefacts.

**`_internal_*` prefix rule:** any field/table prefixed `_internal_` / `_Internal_` is NEVER read by sanitisation, NEVER rendered to external, NEVER exported via vault md mirror.

**Two-layer enforcement:**
- L1 = `lfcs-sanitise-for-external` (12 patterns; strips + sets metadata)
- L2 = `lfcs-sanitisation-verify` (14 patterns INDEPENDENT; re-derived from spec; L1 overlap = 0)
- Both must pass. L2 fail = artefact deleted + log `verified_by_human=NEVER`. No retry without root-cause.
- Human verification gate after L2: operator visually inspects Drive preview before send.

---

## 7. Failure modes — STOP-and-ask vs proceed

### Stop and ask:

- **Ambiguous source data.** RFQ scope email contradicts BoQ on supply boundary. Novel case = stop.
- **Methodology contradictions.** Two Rate Templates match same `scope_type` + `complexity_factors` with different `base_rate_aud`, both `confidence ≥ Medium`. Surface both; ask.
- **`confidence=Needs review` row is the only match** for an active line. Surface the row + `notes` + Rocky-confirmation gap.
- **Override capture failing.** Airtable write non-2xx for 3 consecutive attempts. Offline-queue auto-fallback, but NOTIFY Rocky that downstream submission generation is now blocked.
- **Sanitisation L2 fails.** Already fail-closed at code level. NOTIFY Rocky. No retry. Investigate L1 pattern coverage gap or new schema field L1 missed.
- **Blind boundary breach.** Agent reads file in `comparator_artefact_paths` mid-session. Abort + mark session `ABORTED-BREACH`. No silent continue.
- **Friend-vault structural surprise.** Path missing, format unexpected, category absent. Log + stop. Do not invent.
- **Rocky-only decisions still pending:** Anthropic plan tier; ANTHROPIC_API_KEY scope cap; QS-shared pricing confidentiality (anonymised vs named); second-PM access model.

### Proceed (no Rocky needed):

- Routine pricing inside codified workflows when all preconditions met (grill complete, methodology `confidence ≥ Medium`, no active quarantine, sanitisation seam intact).
- Override capture when participant + reviewer_type + reason_codes + rationale all valid.
- Mirror writes (Airtable ↔ vault md) when data unambiguous.
- Reading any source under read-only scope.
- Logging to dailies / `_Log.md` / `_AgentLog/` / `events.ndjson` per write-protocol.

---

## 8. Open issues / known limits (as of 2026-05-08)

**Built but limited:**
- **Test harness TEST 6 NOT_INDEPENDENT.** `test_harness/run_harness.py` TEST 1 compares recorded constants from `fixtures.py`, not agent-computed totals. +0.00% on 2602 is recorded historical agreement, not forward-looking accuracy. HCB skip = tautology guard. Forward-looking accuracy requires `lfcs-pricing-estimator` (M5) + held-out split.
- **Voice path.** Schema preserved (`verbal_capture` + `verbal_transcript_excerpt` + `capture_mode`). Builder is typed-only v1. Voice build pending Task 0 spike with Rocky + Hasibul.
- **Rollup fields not API-creatable.** `Bids.bid_line_item_overrides` + `Jobs.latest_outcome` need UI creation.
- **`_methodology_lightpole-footing-1.8sq-batch-economy`** has `base_rate_aud=0` + `Needs review`. $892.50 inferred; awaits Hasibul confirm or batch-of-N actuals.
- **Common Misses Patterns at 17** (spec target 16). Review drift next §4.6 pass.

**Not built — milestone gated:**
- **`lfcs-drawing-extract-vision`** (M3). pdftoppm + Vision API. Until: text-pass-only + Rocky's eyes-on every drawing.
- **`lfcs-pricing-estimator`** (M5). Until: manual rates + `lfcs-pricing-history-lookup`.
- **Calibration view trust gate (≥20 jobs)** (M6). Until: ±15% band vs Liam-submitted.
- **Robert parallel-run validation milestone (M-N).** Gated on M6 + Robert protocol agreement.
- **`lfcs-projects`** post-award handoff agent. Separate.

**Operational gaps:**
- **`lfcs-feedback-aggregator` cron.** SKILL.md has the line (`0 18 * * *` UTC = 04:00 AEST). Not installed. Register when ≥3 real overrides accumulated.
- **`_Brain/Open-Threads.md` notification.** Aggregator returns Python objects; cron wrapper + Telegram ping is TODO.
- **Methodology base split.** PAT scope `list_workspaces` returned empty 2026-05-07. Methodology lives unified-base with `_methodology_*` prefix until PAT upgrade or Rocky-created base.
- **Hasibul Quote Tracker as Commercial Events seed.** 9 quotes in friend-vault. Not seeded — Job parents missing. Defer.

---

## Writing lessons

Shared folder: `C:\Users\mclou\lfcs-lessons-learned\`. Both `lfcs-pricing` + `lfcs-orchestrator` read+write. Cowork read-only.

**Triggers (any one):** Rocky flags a miss / pattern repeats ≥2 bids / decision should be default next time / push-back caught a real error / scope or rate convention changes (Rocky-locked).

**Format:** `lesson-{YYYY-MM-DD}-{short-name}.md` (kebab-case).

**Structure (short, plain English):**
- **What happened** — 1–3 sentences. Quote Rocky verbatim where possible.
- **Why it matters** — failure mode + magnitude (cost/scope/time/accuracy).
- **What to do next time** — explicit rule for next session.

**Do NOT write for:** one-off typos, file-naming preferences, in-session resolved ambiguity, internal reasoning errors that didn't affect output. Lessons = cross-session learning, not session-internal corrections.

**Cross-link discipline:** every shared lesson at `C:\Users\mclou\lfcs-lessons-learned\lesson-{date}-{slug}.md` ALSO writes a sibling vault-internal entry at `_Internal/lessons-learned/{date}-{job}-{slug}.md`. Vault-internal keeps full session ref + proposals context; shared holds action-rule distillation Cowork can read. Skip vault-internal only if genuinely portable cross-agent with no OpsMan-specific context (rare).

After writing: cross-link from per-job gaps log (e.g. `_Internal/2630-gaps-log.md`) + one-liner to `_Brain/_Log.md`.

---

## Appendices (extracted siblings)

- **`workflows.md`** — full step procedures for §4.1, §4.2, §4.3, §4.4, §4.6.
- **`blind-comparison-workflow.md`** — full §4.5 procedure + failure modes. Read before invoking any blind-compare round.
- **`architecture-summary.md`** — data architecture, methodology layer, vault structure.
- **`appendix-A-blind-comparison-schema.md`** — schema additions for `Blind Comparison Sessions`, `_internal_quarantined_for_session_id`, `linked_blind_comparison_session`. Read before any Rocky-confirmed schema-change task touching these.
- **`appendix-B-skill-catalogue.md`** — pricing-lane skill catalogue; live / NOT-BUILT status + implementation paths.
