---
title: LFCS Element Taxonomy
created: 2026-05-03
created_by: claude-code-coo (Phase-2 precondition per HQ gap analysis 2026-05-03 Section 5)
status: starter-draft
purpose: Controlled vocabulary for the `element` and `sub_element` fields in pricing-history line files. Prevents free-text drift that breaks aggregate queries at scale.
related:
  - "[[LFCS-Bid-System-Plan-2026-05-03]]"
  - "[[pricing-history/README]]"
  - "[[rate-card]]"
---

# LFCS Element Taxonomy

> **Status:** starter draft. 24 elements across 5 domains. Refine on first use — every new bid that introduces a novel element adds to the taxonomy via append-only entry below + alias-list update.
>
> **Why this exists:** at 50+ jobs, free-text strings like `abutment`, `bridge-abutment`, `RC-abutment`, `Abutment` would all return separate aggregate rows. Pricing-history queries become useless. Controlled vocabulary forces consistency at write time.

## Hard rules

1. **Every `pricing-history/` line file must have `element` matching one of the canonical IDs below.** Validators reject unknown elements at write time.
2. **`sub_element` is also controlled** — listed under each element where applicable.
3. **`aliases:` are accepted on input** — write-time normalisation maps aliases to the canonical ID.
4. **Adding a new element** requires append-only entry below with date + reason + at least one example BOQ line that justified it. No retroactive renames.

## Domains

```
1. CONCRETE             (place + finish)
2. REINFORCEMENT        (place + fix)
3. FORMWORK             (erect + strip + falsework)
4. STRUCTURAL ELEMENTS  (the thing being built)
5. ANCILLARY            (drainage, joints, barriers, install-only)
```

## Canonical elements

### Domain 1 — CONCRETE

| Canonical ID | Sub-elements | Aliases | Notes |
|---|---|---|---|
| `place-finish-concrete` | `abutment`, `wingwall`, `deck`, `approach-slab`, `headstock`, `footing`, `pile-cap`, `slab`, `wall`, `column`, `beam` | `pour-concrete`, `concrete-place`, `pour-finish-concrete`, `place-and-finish-concrete` | Use sub_element to capture WHAT was poured |
| `mass-concrete` | `bulk-fill`, `mud-mat` | `mass-fill`, `unreinforced-concrete` | Use when no reo |
| `concrete-patch-repair` | `renderoc-st06`, `epoxy`, `cementitious` | `patch-repair`, `concrete-repair` | Material captured in `material` field |

### Domain 2 — REINFORCEMENT

| Canonical ID | Sub-elements | Aliases | Notes |
|---|---|---|---|
| `place-fix-reo` | (matches concrete sub_elements) | `place-reo`, `fix-reo`, `tie-reo`, `bar-fixing` | |
| `cut-bend-reo` | — | `bend-cut-reo` | Often subby supply |
| `mesh-install` | `slab-mesh`, `wall-mesh` | `place-mesh`, `fix-mesh` | |

### Domain 3 — FORMWORK

| Canonical ID | Sub-elements | Aliases | Notes |
|---|---|---|---|
| `formwork-erect` | (matches concrete sub_elements) | `erect-formwork`, `formwork-supply-erect`, `formwork-and-falsework` | |
| `formwork-strip` | (matches concrete sub_elements) | `strip-formwork` | Separate line per BOQ convention |
| `falsework` | `propping`, `shoring`, `tower` | `temp-support`, `temporary-works` | High elevations / heavy loads |
| `shop-formwork` | — | `precast-formwork` | Specialised |

### Domain 4 — STRUCTURAL ELEMENTS (whole-element line items)

| Canonical ID | Sub-elements | Aliases | Notes |
|---|---|---|---|
| `rc-abutment` | `bridge`, `retaining-wall` | `concrete-abutment` | Whole element pricing if BOQ rolls F+R+P together |
| `rc-l-wall` | `wingwall`, `retaining-wall`, `200mm`, `300mm` | `concrete-l-wall`, `cantilever-wall` | Sub_element captures wall type AND thickness |
| `rc-deck` | `bridge-deck`, `slab-on-grade`, `suspended-slab` | `concrete-deck` | |
| `rc-approach-slab` | — | `approach-slab` | |
| `rc-headstock` | `bridge` | `headstock-beam`, `pier-cap` | |
| `rc-footing` | `pile-cap`, `pad`, `strip` | — | |
| `rc-curtain-wall` | `abutment-back-wall` | `abutment-curtain-wall` | |
| `rc-pile` | `bored`, `driven`, `cfa` | `concrete-pile` | Usually NOT LFCS scope but sometimes pads/extensions are |

### Domain 5 — ANCILLARY (install + supply where in scope)

| Canonical ID | Sub-elements | Aliases | Notes |
|---|---|---|---|
| `bearing-install` | `laminated-elastomeric`, `pot`, `disc` | `install-bearings` | Supply usually by others |
| `expansion-joint-install` | `bridge`, `approach-slab`, `floor` | `install-expansion-joint` | Supply usually by others |
| `drainage-install` | `bridge-deck`, `subsoil`, `kerb-and-channel` | `install-drainage` | Supply boundary varies |
| `barrier-install` | `precast-parapet`, `steel-thrie-beam`, `concrete-barrier` | `install-barrier` | Supply boundary varies; sub_element captures barrier type |
| `scaffold-walkway` | `girder-launch`, `parapet-install`, `general-access` | `temporary-walkway`, `scaffolding` | LFCS supply+install typical |
| `saw-cut-demolition` | `concrete-wall`, `concrete-slab`, `kerb`, `pavement` | `saw-cut`, `demolish` | Quantity in lin m or m² depending |
| `disposal` | `clean-fill`, `concrete-rubble`, `contaminated` | `dispose`, `cart-away` | Per cubic-metre typical |

## Complexity factors (parallel controlled vocab)

Tags applied to `complexity_factors:` array on each pricing-history line. Multi-select.

| Tag | Meaning | When to apply |
|---|---|---|
| `height-over-3m` | Element above 3m above working surface | Wingwalls, deck soffit, parapets |
| `height-over-6m` | Element above 6m | Tall walls, tower forms |
| `salt-water-proximity` | Within 100m of saltwater (cover spec, durability) | Bridges over coastal canals/estuaries |
| `restricted-access` | Site access constraints (live infrastructure, security, narrow site) | Power station, rail corridor, school |
| `night-shift` | Whole or partial element built on night shift | Bridge over live road |
| `wet-weather-exposed` | Element built without weather cover | Most bridge elements |
| `heavy-reo-density-over-200kgm3` | Reo intensity ≥200 kg/m³ | Bridges, marine structures |
| `heavy-reo-density-over-300kgm3` | Reo intensity ≥300 kg/m³ | High-load bridge elements (the 287kg/m³ Munmorah element falls just below) |
| `cofferdam-required` | Element built within temporary water exclusion | Sub-aqueous abutments |
| `cranage-by-others` | Cranage cost not in LFCS rate | Super-T launches, tilt panels |
| `cranage-included` | Cranage cost in LFCS rate | Parapet lifts, small precast |
| `nfc-drawings` | Built from "Issue for Information" drawings | Pre-award bids on NFC packages |
| `traffic-management-by-others` | TM cost not in LFCS rate | Most bridge work |
| `live-services-nearby` | Active electrical / water / gas within 5m | Brownfield sites |

## Append-only change log

| Date | Element / Tag | Change | Reason | Example BOQ line |
|---|---|---|---|---|
| 2026-05-03 | (initial) | Starter taxonomy | Phase-2 precondition per HQ gap analysis Section 5 | 2602 Munmorah BOQ rows 6.4.1, 6.4.2, 7.2.3.1, 9.2.2 |

## Validator (pseudo, for skill implementation)

```python
def validate_element(line):
    canonical = TAXONOMY.canonical_ids
    aliases = TAXONOMY.alias_to_canonical
    if line["element"] in canonical:
        return line["element"]
    if line["element"] in aliases:
        return aliases[line["element"]]   # normalise
    raise ElementUnknown(f"{line['element']} not in taxonomy. Add to element-taxonomy.md change log first.")
```

## Open questions

- [ ] Should `domain` be a top-level field on each pricing-history line (vs implicit via element)? Probably yes — easier to query "all concrete jobs" in v2 SQLite.
- [ ] Do dayworks lines need their own taxonomy domain, or do they live entirely outside pricing-history? (Currently rate-card.md is the source for dayworks; pricing-history is for lump-sum line items.)
- [ ] How to capture `material` within taxonomy (concrete-50mpa vs concrete-32mpa) — separate field per current schema, or sub-element role? Current schema keeps `material` separate; revisit at first 10-job aggregate query.
