# SKILL — lfcs-drawing-extract-text

## Purpose

Text-extract every drawing PDF in a job folder's `03 - Plans and Specifications/03a - Issued for Construction/` and produce a queryable per-drawing summary at `Drawing-Index.md`. Pass 1 of the two-pass drawing extraction (text-pass cheap + fast; vision-pass via `lfcs-drawing-extract-vision` adds drawn detail).

This is the skill that codifies what HQ did manually for the 2602 Munmorah bid on 2026-05-03.

## Trigger

User says any of:
- "Extract drawings for [job]"
- "Build the drawing index"
- "I dropped the drawings — process them"

Or invoked programmatically by `lfcs-bid-prep-doc` if `Drawing-Index.md` is absent.

## Inputs

Required:
- `job_folder` — absolute path to the job (e.g. `Jobs/Upcoming/2602 - Dec Projects - Munmorah Bridge/`)

Optional:
- `discipline_filter` — `structural-only`, `civil-only`, `all` (default: `all`, but flag civil as `lfcs_scope: reference-only` if structural drawings are also present)
- `include_subfolders` — boolean (default: false; only scan `03a/`)

## Behaviour

1. **Discover PDFs** in `{job_folder}/03 - Plans and Specifications/03a - Issued for Construction/`. Skip non-PDF files. If zero PDFs, abort + tell user.
2. **For each PDF:**
   - Read with PDF text extraction (Cowork's Read tool handles PDFs natively; CC CLI can use pdfplumber or pdftotext).
   - Parse cover sheet — extract `drawing_no`, `rev`, `title`, `date_issued`, `drafter`, `job_manager`, `designer`, `verifier`, `sheet_size`, `discipline`, `office`, `job_no`, `lfcs_scope` (cover-only / primary / reference-only / reference-only-but-LFCS-risk).
   - Per page: extract `Shows`, `Geometry`, `Elements drawn / specified`, `Cross-references`, `Construction notes` (verbatim quotes), `Tags`, `Risks raised on sheet`.
   - Apply `lfcs-relevant tags` per the 2602 template (e.g. `material:Renderoc-ST06`, `geometry:34m-overall`, `risk:live-electrical`, `discrepancy:8.2m-vs-9.0m-carriageway`).
3. **Build cross-cutting tables:**
   - Document Set Summary (one row per PDF set)
   - Universal queries section (greppable tag patterns)
   - Cross-drawing discrepancies / clashes (REQUIRES RFI BEFORE PRICING)
   - Items mentioned in BOQ but not visible in drawings (if `boq-normalised.json` exists)
   - Items visible in drawings not priced in BOQ (if `boq-normalised.json` exists)
4. **Write `{job_folder}/03 - Plans and Specifications/03a - Issued for Construction/Drawing-Index.md`** matching the 2602 template structure exactly (frontmatter, document set summary, per-drawing blocks, cross-references, future-project pattern note at end).
5. **Add `confidence flags` section** at end of doc — text-extract limitations, mandatory vision-pass note pointing to `lfcs-drawing-extract-vision` (or Phase 0 manual eyes-on for THIS bid).
6. **Append project log + daily note** per AI Team Protocol.
7. **After `Drawing-Index.md` written + committed, invoke `lfcs-airtable-sync`** with `vault_path={Drawing-Index.md}` and `target_table=Drawings,Drawing Elements`. Failure non-blocking per the Airtable behaviour section above.

## Files to read (in order)

```
HQ-Vault/_System/CLAUDE.md                                       ← AI Team Protocol
HQ-Vault/11_OpsMan_LFCS/_Brain/CLAUDE.md                         ← LFCS extensions
HQ-Vault/11_OpsMan_LFCS/Operations/Jobs/Upcoming/2602 - Dec Projects - Munmorah Bridge/03 - Plans and Specifications/03a - Issued for Construction/Drawing-Index.md  ← regression fixture / template
HQ-Vault/11_OpsMan_LFCS/Operations/lfcs-standards/folder-spec.md ← naming + paths
{job_folder}/03 - Plans and Specifications/03a - Issued for Construction/*.pdf  ← inputs
{job_folder}/02 - Scope and Pricing/02b - BOQ and Rate Schedules/*.xlsx  ← optional, for cross-check
```

## Airtable behaviour

- **Reads:** `Jobs` (find Job record by Job Number for FK link). `Drawings` (check if rows already exist for this job to avoid duplicate creates).
- **Writes:** `Drawings` (one row per source PDF; populates Discipline, PDF Page, Source PDF URL, AI Summary, Vault MD Path, Job link). `Drawing Elements` (any elements text-pass identified, with Confidence = `Medium` for text-only — Phase-2 vision pass via `lfcs-drawing-extract-vision` upgrades these rows to higher Confidence). Calls `lfcs-airtable-sync` as final step with `Drawing-Index.md` as input + `target_table=Drawings,Drawing Elements`.
- **Idempotency:** `Drawings` upserted by Drawing Number. `Drawing Elements` upserted by Element Name. Re-running on the same drawings = same Airtable state.

## Output format

Single markdown file: `Drawing-Index.md` matching the 2602 template structure.

To user (terminal):

```
✓ Drawing-Index.md generated for {job_no}
  PDFs processed: {n}
  Disciplines: {list}
  Drawings tagged primary: {n} | reference-only: {n} | cover-only: {n}
  Discrepancies flagged: {n}
  Tags extracted: {n}

  Drawing-Index path: {abs path}

  ⚠ MANDATORY NEXT STEP — vision-pass:
    Per LFCS Bid System plan Phase 0, vision-pass is mandatory before pricing.
    Either: Path A — eyes-on review by Rocky.
            Path B — pdftoppm + Cowork drag-drop.
            Path C (Phase 2) — lfcs-drawing-extract-vision skill.

  Next skills:
    - lfcs-boq-cross-check (Phase 2) — flag BOQ↔drawing misalignment
    - lfcs-bid-prep-doc — generate 00-Bid-Prep.md from extracts
```

## Hard rules

- **NEVER claim text-extract is sufficient.** Output always flags the vision-pass mandate. Drawings have drawn-only content (dimensions outside text labels, hatching, section markers, detail bubbles, drawn clashes) that text extraction silently misses.
- **Verbatim construction notes.** Reproduce notes from drawings exactly — no paraphrase. Italicise + quote.
- **No invention.** If a field can't be extracted from the PDF text, leave it `TBC` or omit. Never plausible-fiction.
- **Append-only on Drawing-Index.md.** If file exists, abort + ask user (don't silently overwrite). User decides: regenerate from scratch (delete first) or merge.
- **Regression fixture:** running on 2602 PDFs must reproduce or improve the existing `Drawing-Index.md`. Less detail = blocking issue.
- **Read-before-edit** every input PDF + every template each invocation.
- **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

- 2602 Munmorah `Drawing-Index.md` (regression fixture)
- folder-spec.md
- (optional) `boq-normalised.json` from `lfcs-boq-parse` for cross-references

## Failure modes

| Failure | Detection | Recovery |
|---|---|---|
| Zero PDFs in 03a | Pre-scan | Abort, tell user where to drop drawings |
| PDF unreadable / scanned-image-only | Text extraction returns empty | Flag drawing as "vision-pass-only required", include placeholder block in Drawing-Index |
| Drawing-Index.md already exists | Pre-check | Abort + ask user (regenerate from scratch or merge) |
| Cover sheet missing expected fields | Per-PDF validation | Tag drawing as `lfcs_scope: needs-review`, flag in output |
