# SKILL — lfcs-project-init

## Purpose

**Single-skill orchestrator for new-job intake.** Open Cowork in a fresh job folder, run this one skill, get the full Phase-1 setup: folder structure + per-job CLAUDE.md + extracted Drawing-Index + parsed BOQ + drafted Bid-Prep + Pre-Call-Questions + Inclusions-Exclusions, all linked into Airtable.

Codifies the transcript's "open the folder, run ONE skill, get full setup" pattern (per cowork-lfcs Phase 6 transcript-gap fix). Replaces 5 separate manual skill invocations with a single orchestrator that runs them in order, with abort-on-gap behaviour at each step.

Created 2026-05-04 PM by cowork-lfcs Phase 6.

## Trigger

User says any of:
- "New job arrived — set me up"
- "Init project [job_no]"
- "Run project init on [folder]"
- "Whole bid prep stack on [job]"
- "I dropped the source files — do everything"

Or invoked programmatically by `lfcs-tender-correspondence` (v2) when a tender pack arrives.

## Inputs

Required:
- `job_no` — 4-digit, year-prefixed (e.g. `2602`)
- `client` — head contractor name
- `site` — short site/project name
- `bid_due` (if upcoming) OR `start_date` (if awarded)

Optional (will pass through to downstream skills):
- `end_client`, `designer`, `client_signatory_*`, `type` (price / dayworks / etc.), `qs_call`, `discipline_filter` (for drawing extract)
- `uploads_path` (v3+) — explicit override for Cowork uploads folder location. Defaults to auto-detect from session context; only set if running on a non-standard surface or testing.
- `auto_route_uploads` (v3+, boolean, default `true`) — controls whether step 1.5 runs. Set `false` to skip uploads routing (e.g. if you've already manually placed files in vault folders and want orchestrator to go straight to step 2).

**Workflow note (v3+):** the orchestrator now handles BOTH workflows seamlessly:
- **(A) Files dropped via Cowork chat upload** — step 1.5 detects + routes them into vault automatically with one-prompt confirm.
- **(B) Files placed directly into vault folders** (Windows Explorer / git pull / Drive sync / etc.) — step 1.5 is a no-op (no uploads detected), step 2 confirms files are present, orchestrator proceeds.

Either way, you don't need to think about WHERE files came from — orchestrator handles routing.

## Behaviour

Sequence — each step's success-or-abort feeds the next. On any abort, log to `_System/Conflicts.md` and stop (don't cascade failures). Fail-safe: if step 1 succeeds but the user hasn't dropped source files, exit cleanly with instruction.

1. **Invoke `lfcs-job-scaffold`** with the inputs above. Creates the 11-section folder tree + `00-brief.md` + `README.md` + per-job `CLAUDE.md` (v3 of scaffold). Job row upserted to Airtable Jobs table via `lfcs-airtable-sync`. Output: absolute path of new folder + list of TBC fields in `00-brief.md`.

1.5. **Detect + route uploaded files from Cowork chat** (added v3 — Phase 7.5; closes the "drag-and-drop into Cowork chat" workflow gap). After scaffold but BEFORE the source-file check, detect files in the current session's Cowork uploads folder. The uploads location is session-specific — for Cowork desktop sessions it's typically at the path documented in the session's system-prompt file-handling rules block (under `notes_on_user_uploaded_files` — usually `{user_appdata}/Claude/local-agent-mode-sessions/{...}/uploads/`). For headless / non-Cowork surfaces (CC CLI), this step is a no-op.

   For each file found:
   - Classify by extension + filename pattern:
     - `*.xlsx` → BOQ → propose move to `{job_folder}/02 - Scope and Pricing/02b - BOQ and Rate Schedules/`
     - `*.pdf` matching spec patterns (`FRBR_R*`, `FRBR_B*`, `R0*`, `B0*`-`B999`, `AS*`, `AS-NZS*`, `NZS*`, `SydneyWater_*`, filename contains "spec") → spec PDF → propose move to `{job_folder}/03 - Plans and Specifications/03a - Issued for Construction/` AND flag for `lfcs-spec-summarise` invocation in step 3.5
     - `*.pdf` matching RFI patterns (filename starts `RFI` or contains "RFI") → RFI doc → propose move to `{job_folder}/06 - Correspondence/06b - RFIs/`
     - Other `*.pdf` → drawing → propose move to `{job_folder}/03 - Plans and Specifications/03a - Issued for Construction/`
     - `*.docx` / `*.doc` → likely contract or correspondence → ask user (default: `06 - Correspondence/06a - Emails/`)
     - `*.zip` → if practical, unzip first; else propose move to `02a - Quotes and Estimates/` for manual unpack later
     - Anything else → ask user explicitly
   - Show ONE proposed-routing table with all detected files in a single prompt:
     ```
     I see {n} files in uploads. Proposed routing:
       file1.pdf  → 03a (drawing)
       file2.xlsx → 02b (BOQ)
       FRBR_R11_E5R8.pdf → 03a (spec — will run lfcs-spec-summarise in step 3.5)
       RFI42.pdf → 06b (RFI)
     Confirm? [y/n/per-file-override]
     ```
   - On confirm: COPY (not move) files into vault paths. Originals stay in uploads as backup; user cleans up manually OR via future `lfcs-uploads-cleanup` skill (not yet built).
   - **Idempotent re-runs:** if target path already has a file with the same name, compare size/mtime/hash. Skip if identical; prompt user if different ("uploaded version is newer/larger — replace existing or skip?").
   - If NO files detected in uploads OR session is non-Cowork (no uploads folder accessible), skip this step cleanly and proceed to step 2.

2. **Pause-and-check** — scan `{job_folder}/03 - Plans and Specifications/03a - Issued for Construction/` for `*.pdf` files AND `{job_folder}/02 - Scope and Pricing/02b - BOQ and Rate Schedules/` for `*.xlsx`. If either folder is empty (e.g. step 1.5 was a no-op or only partial), halt with message:
   ```
   ✓ Folder + brief + README + CLAUDE.md scaffolded for {job_no} {client} {site}.
   ✓ Job row upserted to Airtable Jobs.
   {if step 1.5 detected + moved files: ✓ Routed N files from Cowork uploads into vault.}

   ⚠ Source files still missing in vault. Drop:
     - Drawings → {job_folder}/03 - Plans and Specifications/03a - Issued for Construction/
     - BOQ xlsx → {job_folder}/02 - Scope and Pricing/02b - BOQ and Rate Schedules/

   Either drop directly into vault folders, OR drag-and-drop into the next Cowork chat message and re-invoke `lfcs-project-init` — step 1.5 will route the uploads automatically.
   ```
   Resume on re-invocation by detecting the folder is already scaffolded (lfcs-job-scaffold's idempotent abort kicks in). Skip steps 1-1.5 and proceed to 3 if files are now present.

3. **Invoke `lfcs-drawing-extract-text`** with `job_folder = {abs path}`. Generates `Drawing-Index.md` per the 2602 template + Drawings rows + Drawing Element rows in Airtable (text-pass, Confidence=Medium until vision-pass run separately). On abort (e.g. `Drawing-Index.md` already exists), surface to user with regenerate-vs-merge choice.

3.5. **Invoke `lfcs-spec-summarise`** (added v2 — Phase 7) with `job_folder`. Auto-discovers spec PDFs in `03a/` matching patterns `FRBR_R*`, `R0*`, `B*`, `AS*`, `SydneyWater_*`, etc. For each found spec, generates `{spec_code}-summary.md` in `Operations/lfcs-standards/specs/` + upserts Airtable Specifications row with summary + Hold Points Count + Witness Points Count. Skips silently if no specs found. Closes transcript-gap #2 (spec-mirror MD for fast AI ingest by downstream skills — saves tokens on every subsequent skill that touches a spec-governed item).

4. **Invoke `lfcs-boq-parse`** with `job_folder`. Generates `boq-normalised.json` + `boq-quantities-at-a-glance.md`. Updates `00-brief.md` quantities-at-a-glance section append-only. On abort (multiple xlsx, ambiguous), surface to user.

5. **Invoke `lfcs-bid-prep-doc`** with `job_folder`. Generates `00-Bid-Prep.md` from the brief + drawing-index + boq-normalised. Pre-flight: requires the 3 inputs from steps 1+3+4 to exist; abort with helpful message if any missing.

6. **Invoke `lfcs-precall-questions`** with `job_folder` + `call_date = bid_due - 2` (default; user can override). Generates `Pre-Call-Questions-{call_date}.md` in `06c`. On abort (file exists for that date), surface.

7. **Invoke `lfcs-incl-excl-draft`** with `job_folder`. Generates `Inclusions-Exclusions.md` in `02a`. On abort (file exists), surface.

8. **Final sync verify** — call `lfcs-airtable-sync mode=audit-only` on the whole `{job_folder}` to confirm Airtable state matches vault state. Log result to `_AgentLog/airtable-sync.log`.

9. **Append project log + daily note** per AI Team Protocol — single one-liner summarising the orchestration run + per-skill outcome.

10. **Output to user** — single summary block:
    ```
    ✓ Project init complete for {job_no} {client} {site}
      Path: {abs path}

      Generated:
        - 00-brief.md ({n} TBC fields)
        - 00-Bid-Prep.md
        - README.md
        - CLAUDE.md (per-job AI context)
        - 03a/Drawing-Index.md ({n} drawings, Confidence Medium pending vision-pass)
        - 02b/boq-normalised.json + boq-quantities-at-a-glance.md
        - 06c/Pre-Call-Questions-{call_date}.md ({n} questions)
        - 02a/Inclusions-Exclusions.md ({n} inclusions, {n} exclusions)

      Airtable seeded:
        - Jobs: 1 row (upsert)
        - Drawings: {n} rows
        - Drawing Elements: {n} rows
        - All linked to Job {rec_id}

      ⚠ MANDATORY NEXT STEPS:
        1. Vision-pass each drawing (Phase 0 per LFCS Bid System plan §6)
           - Either Path A eyes-on review by Rocky
           - Or Path B pdftoppm + Cowork drag-drop
           - Or Path C lfcs-drawing-extract-vision (when v2 lands)
        2. Pre-Pricing-Grill (per pricing-checklist.md **Phase 0** — MANDATORY before any pricing)
           - Surface Q1 through Q7 with Rocky before any rate set (Q1 supply, Q2 site mgmt, Q3 QA, Q4 programme, Q5 productivity, Q6 commercial posture, Q7 sanity check)
           - Locks supply boundaries + commercial posture upfront
           - Output: `02b/Pre-Pricing-Grill-{date}.md`
        3. Read per-job CLAUDE.md before any further task on this job
    ```

## Files to read (in order)

```
HQ-Vault/_System/CLAUDE.md                                       ← AI Team Protocol
HQ-Vault/11_OpsMan_LFCS/_Brain/CLAUDE.md                         ← LFCS extensions (incl Airtable schema cheatsheet)
HQ-Vault/11_OpsMan_LFCS/Operations/skills/_README.md             ← skill catalog rules
HQ-Vault/11_OpsMan_LFCS/Operations/lfcs-standards/folder-spec.md ← canonical folder structure
HQ-Vault/11_OpsMan_LFCS/Operations/lfcs-standards/pricing-checklist.md  ← Pre-Pricing-Grill required pre-flight
HQ-Vault/11_OpsMan_LFCS/Operations/Jobs/Upcoming/2602 - Dec Projects - Munmorah Bridge/  ← canonical regression fixture (full Phase 1 outputs)
HQ-Vault/11_OpsMan_LFCS/Operations/Jobs/Upcoming/2626 - Mack Civil - Stormwater Pit EXA01A-08/  ← second regression fixture (FRP-install-only TfNSW dayworks pattern)
```

Each downstream skill (`lfcs-job-scaffold`, `lfcs-drawing-extract-text`, etc) has its own files-to-read list; orchestrator inherits.

## Airtable behaviour

- **Reads:** Jobs (collision check before scaffold), all 11 tables transitively via the called skills.
- **Writes:** delegated to each called skill, which routes through `lfcs-airtable-sync`. Final step 8 above does an `audit-only` sync to verify vault ↔ Airtable consistency.
- **Idempotency:** every step is idempotent (lfcs-job-scaffold aborts on existing folder; lfcs-drawing-extract-text aborts on existing Drawing-Index.md; lfcs-bid-prep-doc aborts on existing 00-Bid-Prep.md). Re-running on same `job_no` after a partial failure resumes from the next missing artefact.

## Output format

To user: see step 10 above (single summary block).

To `_AgentLog/airtable-sync.log` (per the audit-only sync in step 8):
```
2026-05-04 16:00 — lfcs-project-init — table=ALL job=2627 mode=audit-only
  vault_path: HQ-Vault/.../2627 - {client} - {site}/
  vault_state: 11 sections + 00-brief + CLAUDE.md + Drawing-Index.md + boq-normalised.json + 00-Bid-Prep.md + Pre-Call-Questions + Inclusions-Exclusions
  airtable_state: Jobs=1, Drawings=N, Drawing Elements=N (no Bids/Specs/RFIs yet — those come post-pricing/post-call)
  diff: clean ✓
  wall-clock: 18.4s
```

To `_Brain/_Log.md` (one-liner per AI Team Protocol):
```
- YYYY-MM-DD HH:MM — cowork-lfcs — lfcs-project-init complete for {job_no} {client} {site}; {N} skills called; {M} Airtable rows seeded; vault ↔ Airtable consistent. → [[01_Daily/{today}#HH:MM]] + [[Jobs/Upcoming/{folder}/CLAUDE]]
```

## Hard rules

- **All-or-step-clean.** If any step aborts, halt and report. Do NOT skip ahead — downstream skills depend on upstream artefacts. The exception is the source-files pause at step 2 (clean halt with resume path).
- **Idempotent re-runs.** Re-invoking on a partially-completed job folder resumes from the next missing artefact, never re-creates existing ones.
- **Step 1.5 (uploads routing) — ALWAYS confirm before moving** (v3+). Never silently move uploaded files into vault. Show the proposed routing table in one prompt; on confirm, COPY (not move). Originals stay in uploads as backup. Idempotent — re-runs hash-check existing target files; skip identical, prompt different.
- **Pre-Pricing-Grill is NOT in this orchestrator.** Per pricing-checklist.md **Phase 0** (added 2026-05-04 PM late; sits BEFORE Phase 1 source intake), the grill is a Rocky-interactive surface that runs BEFORE any rate is set — that's a synchronous chat in Cowork, not an orchestrated skill chain. Orchestrator hands off to "next mandatory step: Pre-Pricing-Grill" in the output. Question labels Q1-Q7 (not Q-A through Q-G — earlier concept notes used the letter scheme; Q1-Q7 is now canonical).
- **Vision-pass is NOT in this orchestrator** — text-pass only via lfcs-drawing-extract-text. Vision-pass requires Phase 2 v2 skill OR Rocky's eyes-on review (Phase 0 per LFCS Bid System plan §6 — mandatory before pricing finalisation). Orchestrator hands off.
- **Vault markdown is source of truth.** Every Airtable write is downstream of a vault commit (each called skill enforces this).
- **No deletions** of any kind. Step 1.5 COPIES uploads, never deletes them — user cleans uploads manually or via future skill.
- **Read-before-edit** every input + every template each invocation.

## Dependencies

- `lfcs-job-scaffold` v3+ (per-job CLAUDE.md generation)
- `lfcs-drawing-extract-text` v2+ (Airtable behaviour section)
- `lfcs-boq-parse` v2+
- `lfcs-bid-prep-doc` v2+
- `lfcs-precall-questions` v2+
- `lfcs-incl-excl-draft` v2+
- `lfcs-airtable-sync` v1+ (called transitively by each above + directly in step 8)
- 2602 Munmorah Bridge folder + 2626 Mack Civil Stormwater Pit folder (canonical regression fixtures — orchestrator output for any future job must reproduce or improve)

## Regression test

Running `lfcs-project-init` on a synthetic test job (e.g. `2698 - Test Client - Test Site`) with fresh source files dropped should produce:
1. Folder tree per folder-spec.md ✓
2. 00-brief.md, 00-Bid-Prep.md, README.md, CLAUDE.md ✓
3. 03a/Drawing-Index.md (Confidence=Medium per text-pass) ✓
4. 02b/boq-normalised.json + quantities-at-a-glance.md ✓
5. 06c/Pre-Call-Questions-{call_date}.md ✓
6. 02a/Inclusions-Exclusions.md ✓
7. Airtable Jobs row + Drawings rows + Drawing Element rows seeded ✓
8. Vault ↔ Airtable audit clean ✓

Re-running on the same job folder should resume from any partial state without duplication (each downstream skill's idempotency handles this).

## Failure modes

| Failure | Detection | Recovery |
|---|---|---|
| job_no collision (folder already exists with content) | step 1 abort | Halt; ask user — append to existing folder OR rename |
| No source files in 03a + 02b after step 2 pause | step 2 scan | Clean halt with instruction; resume on re-invocation |
| Drawing-Index.md or 00-Bid-Prep.md or other artefact already exists | each step's pre-check | Halt, surface to user with regenerate-vs-merge choice |
| BOQ xlsx ambiguous (multiple xlsx in 02b) | step 4 boq-parse abort | Surface, ask user which xlsx is the real BOQ |
| Airtable write failure on any called skill | each skill's lfcs-airtable-sync call | Per Phase 2 hard rule: NON-BLOCKING. Skill considered successful, failure logged to `_System/Conflicts.md`, orchestrator continues to next step |
| Vault ↔ Airtable diff at step 8 audit | audit-only sync diff | Surface diff to user; recommend manual reconciliation OR re-running specific upstream skill |
