---
title: 2631 dry-run self-test of lfo-bid-lifecycle (Build 5)
job_no: 2631
date: 2026-05-08
authored_by: claude-code-orchestrator
mode: dry-run-self-test (NO live submission, NO Airtable writes, NO sanitised artefacts)
purpose: End-to-end exercise of the v2 lifecycle — autonomous intake → handoff → reverse-engineer → sanity-check → close. Verify: priority chain runs, handoff bus carries, envelope completes, total Rocky touchpoints minimised.
NOT_FOR_EXTERNAL_DISTRIBUTION: true
constraints:
  - lfp terminal is not active in this session — pricer responses are STUBBED with the output the worker would produce given the prompts
  - daemon not running — handoff file mtimes still update; phone notifications skipped (sandbox network egress blocked anyway)
  - web research used real WebSearch tool calls (counted against 10/bid budget)
  - no external sanitisation, no email send, no Airtable writes
---

# 2631 Dry-Run Self-Test

## Activation command

Rocky (lfo terminal):
```
start bid 2631
```

(No explicit inbound path — skill defaults to scanning vault `Operations/Jobs/Upcoming/2631 - .../`.)

## Pre-flight (5 sec)

- [x] state.json read: `active_bid_id=null`. Proceed.
- [x] Inbound path validated: `Operations/Jobs/Upcoming/2631 - Solutions Plus - Field of Play Hornsby/` exists with drawings filed (per per-job CLAUDE.md, 2026-05-05).
- [x] Spawn orchestrator session log: `_Internal/orchestrator-sessions/session-{uuid}-2631.md` (stubbed — would be real on live run).
- [x] state.json updated: `active_bid_id=2631, current_phase=phase-1-intake, bid_started_at=2026-05-08T<now>`.

## Phase 1 — Autonomous intake (priority chain on 6 + bid-specific questions)

Read job folder + per-job CLAUDE.md. Pre-screen extracts:
- HC: Solutions Plus (Built Pty Ltd)
- End client: Hornsby Shire Council (Old Mans Valley Field of Play project; $12M federal grant + Council match)
- Site: Old Mans Valley, Hornsby NSW (postcode 2077)
- Scope: pavement / concrete paving finishes per HPE-TEN-CI-OMV FTL pack
- Drawings: filed in 03a, dated up to 2026-03 (90% Design)
- **CROSS-REFERENCE:** Hasibul has signed S01-2275-011 with Solutions Plus Built Pty Ltd at $95,000 ex-GST for what appears to be the same site. **PR 2631 may be a separate later round OR the same scope as 01-2275.** Per-job CLAUDE.md flags this as needing Rocky confirmation.

Priority chain run on 6 standing questions + 1 bid-specific:

| # | Question | Step yielding answer | Decision | Confidence | Source |
|---|----------|---------------------|----------|------------|--------|
| 1 | Q-1 Scope | Step 3 precedent | "concrete paving finishes per HPE-TEN-CI-OMV FTL pack: formwork edges + steel-fix mesh + concrete place+finish + curing for FTL pavement; no bleachers / no walls / no precast — slab-only scope" | 80% | Per-job CLAUDE.md provisional + matches Hornsby drawings filed; confirmed against Hasibul S01-2275-011 scope ($95K signed sub) which is paving FTL only |
| 2 | Q-2 Site exposure | Step 1 standing-context | "inland — Hornsby suburban (postcode 2077), no coastal exposure, no immersion, no tidal" | 95% | Standing-context §1 + postcode 2077 = inland Sydney metro |
| 3 | Q-3 Labour rate | Step 1 standing-context | "$95/hr blended per §1.5 default" | 90% | §1.5 default; no precedent override on Hornsby paving |
| 4 | Q-4 Margin/contingency | Step 1 standing-context | "Labour ×1.10×1.15=1.265; Materials ×1.15×1.10=1.265 per §1.5 locked formula" | 95% | §1.5 locked |
| 5 | Q-5 Adverse weather | Step 6 educated assumption | "exclude as variation per default — Hornsby is sheltered semi-urban; programme assumed <8 weeks for paving package; no override signal" | 70% | §13.3 stub not yet codified; precedent absent; default applies but flag for Rocky if programme >8 weeks |
| 6 | Q-6 LAFHA | Step 1 §13.1 LAFHA-via-Botany-distance | "OUT — Botany → Hornsby ~50 min via Google Maps off-peak" | 95% | §13.1 deterministic rule (<=75 min = OUT) |
| 7 | **BID-SPECIFIC: Is 2631 a re-bid of S01-2275 or separate package?** | Step 6 educated assumption | "Likely separate package OR variation — different bid number, drawings filed in different round; but signed sub is for $95K which is small for a $12M+ project, suggesting tier-2 partial scope" | 50% | Cross-reference flag in per-job CLAUDE.md; Hasibul's vault notes; **CONFIDENCE BELOW 60% → FLAG FOR ROCKY** |

Auto-decided: 6 (#1–#6, all ≥70% confidence; #5 flagged for "if programme >8 weeks" caveat).
Flagged for Rocky: 1 (#7 bid-specific).
Open (genuinely unknowable): 0.

Web research budget consumed: 0 calls (Phase 1 used standing-context + precedent + per-job CLAUDE.md only).

**Assumptions log written** to `_Internal/assumptions-log-2631.md` (would be real on live run).

**Rocky-input gate fires:** state.json `rocky_gate_active=true`, `rocky_gate_question="Is 2631 the same scope as Hasibul's signed S01-2275 ($95K), a re-bid round, or a separate sub-package within the $12M Field of Play project?"`. Daemon would notify phone after 30 min. **First Rocky touchpoint.**

Stub Rocky response: "Separate sub-package — Hasibul's $95K is the FTL paving round 1; 2631 is round 2 with additional decorative finishes per the HPE pack. Same site, different scope slice." → orchestrator clears gate, advances to Phase 2.

## Phase 2 — Standard exclusions (auto-applied)

`lfo-standard-exclusions-apply` runs on 2629 three-tier shape:

- Tier 1 (Standard Exclusions, 1–10): all auto-applied (always-out items).
- Tier 2 (Preliminaries — HC supplies, 11–28): auto-applied minus 2 items flagged as `always-RFI` for paving-specific clarification (concrete supply confirmation: dispatched vs site-batched; Hilti chemical anchors not relevant for FTL paving — dropped).
- Tier 3 (Detailed Exclusions, 29+): job-specific carve-outs from drawings:
  - 29 — bulk earthworks + sub-base (by earthworks sub)
  - 30 — line marking (by paint contractor)
  - 31 — paving units laid as units (e.g. brick edge — by landscape sub)
  - 32 — surface retarder + exposed-aggregate finish per Dulux Avista TDS — flagged as MAYBE-IN per drawings; **flag for Rocky** if this is decorative paving for LFCS or paint-sub
  - 33 — sealer per Fosroc Concure TDS — FLAGGED, may be in scope
  - ... (truncated)

Skeleton seeded at `_Internal/exclusions/exclusions-2631.md` (stubbed — would be real on live run).

Auto-decided: 28 of 30 exclusions.
Flagged for Rocky: 2 (#32 surface retarder, #33 sealer — sub vs LFCS scope).

These appended to assumptions log as Phase 2 rows. Surfaced in batched gate alongside any remaining Phase 1 flags. Stub Rocky response: "Surface retarder + sealer = LFCS scope per HPE-TEN pack; treat as inclusions, not exclusions." → orchestrator updates skeleton, advances to Phase 3.

## Phase 3 — Worker pricing via handoff (STUBBED)

Orchestrator drafts prompt sequence + writes first prompt to `orch-to-pricer.md` via `lfo-handoff-watcher`:

```
<!-- orch-msg-start bid=2631 ts=... phase=phase-3-worker msg-index=1 -->
## Bid 2631 — Phase 3 worker prompt 1 — drawing extract

Run lfcs-drawing-extract-text on:
- 2631_DWG_HPE-OMV-FTL-IFC_260320_Reduced.pdf
- 2631_DWG_Pavement-Plan-Unmarked.pdf
- 2631_DWG_Concrete-Paving-Finishes-Plan.pdf
- 2631_DWG_Finish-Detail.pdf
- 2631_DWG_Pavement-MarkedUp-BlownUp.pdf

Then lfcs-drawing-extract-vision on the dense pavement-plan pages
(per CLAUDE.md §4.1 step 4).

Intake envelope (locked):
- Q-1 scope: paving FTL slab + decorative finishes (incl. surface retarder + sealer per Rocky's Phase 2 confirmation)
- Q-2 inland (postcode 2077)
- Q-3 $95/hr blended
- Q-4 labour ×1.265 / materials ×1.265
- Q-5 weather: exclude as variation (10wk programme assumed)
- Q-6 LAFHA out
<!-- orch-msg-end -->
```

**STUB pricer response** (what `lfp-handoff-watcher` would produce given the prompt):
- Drawing index produced: 4 pavement plans + 1 finish detail = 47 elements identified (slab edges, joint patterns, FTL geometry, ramp transitions, exposed-aggregate finish zones)
- ~620 m² of paving slab; ~85 m of edge formwork; ~800 m of joint sawing; SL82 mesh; standard 32 MPa concrete

**Subsequent handoff cycles** (stubbed): BoQ parse (no BoQ supplied → take-off from drawings), bid prep doc, Phase 0 grill (envelope pre-pended → skip Q-A0/A1/A2 etc; only Q-D1/D2 programme + Q-E productivity + Q-F1 commercial posture remain), first-pass priced take-off.

**Bottom-up SEALED** (stub): direct cost ~$95K labour + $12K materials → loaded ~$135K.

state.json: `current_phase=phase-3-sealed`, `last_pricer_to_orch_mtime=<iso>`.

## Phase 3.5 — Reverse-engineer envelope (parallel)

Skill: `lfo-reverse-engineer-budget` (skip_quarantine=false for live; skip_quarantine=true for this dry-run since both bottom-up and envelope visible to test analysis).

**Web research (real, sandbox-permitted via WebSearch tool):**
- Query 1: "Solutions Plus Hornsby Field of Play tender contract value Council" → no direct hit
- Query 2: "Hornsby Council Field of Play capital works tender award" → $12M federal grant + Council match disclosed; no specific contractor breakdown

Budget: 2 of 10 calls used.

**Findings:**
- Total project value (Council + grant): $24M+ for full Old Mans Valley Field of Play
- Solutions Plus likely has a single sub-package (FTL paving + decorative finishes) within larger HPE-led delivery
- Per Hasibul's signed S01-2275-011: $95K already locked for paving round 1 → 2631 is a SEPARATE sub-package (Rocky-confirmed in Phase 1)

**Skill output (envelope):**
- HC contract value (assumed): unable to determine specific value for Solutions Plus's slice. Use scope-comparable proxy: similar Council paving sub-packages ~$80K–$200K based on industry standard for ~600 m² decorative FTL.
- Allocation %: 70-90% of Solutions Plus's slice (FTL paving is mostly LFCS-scope concrete + finishes; little outside)
- HC margin: 12% (Solutions Plus tier-2-civil)
- Within-package deductions: 30-45% (concrete supply 20-25%, mesh 5-7%, plant 5-10%, services 3-5%; standard 32 MPa concrete, no premium materials)
- **Envelope: $50K – $145K ex GST** (mid $97K)
- Confidence: 35% (very wide; no public contract value; proxied from comparable subs)

**Comparison vs bottom-up $135K:**
- Bottom-up at upper end of envelope; +39% over midpoint, -7% under upper bound → **inside envelope (±15% of upper)** = confident submission flag
- Note: confidence 35% means envelope is informational only; sanity-check should not act on it. Bottom-up is the authored price.

Output written to `_Internal/quarantined/budget-envelope-2631.md` (stubbed for dry-run).

## Phase 4 — Sanity-check + envelope reveal

Orchestrator unquarantines envelope, writes `_Internal/budget-envelope-comparison-2631.md`:
- Bottom-up: $135K
- Envelope: $50K – $145K (mid $97K, confidence 35% — too low for sanity-check action)
- Outcome flag: **inside envelope upper bound** (close to $145K), but confidence too low to call confidently
- Action: sanity-check proceeds; envelope is one weak input

Stubbed override capture: 0 overrides (small bid, simple scope, agent's bottom-up matches Rocky's expectations). state.json `current_phase=phase-4-complete`.

## Phase 5 — Blind comparison

Skipped: skip_blind=true by default; Rocky did not name a comparator at start command.

## Phase 6 — Send (Rocky-gated)

**Hard case 6:** wait for Rocky-typed "send" or equivalent.

state.json: `rocky_gate_active=true`, `rocky_gate_question="Submission ready: bid 2631 priced at $135K ex GST, exclusions list seeded, assumptions log clean. Type 'send' to authorise external submission."`. Daemon notifies phone after 30 min.

**Second Rocky touchpoint.**

For dry-run: stop here. Do NOT execute Phase 6 send (no L1/L2 sanitisation, no Drive upload, no email, no Airtable Status flip).

## Phase 7 — Lessons-write + close (skipped in dry-run)

Would normally:
1. lfo-lessons-write writes session lessons (none new this dry-run; system worked as designed).
2. _Brain/_Log.md append.
3. state.json reset.
4. Phone notify "bid 2631 ready for review."
5. Process queue.md (none queued).

## Touchpoint summary

Total Rocky touchpoints in dry-run: **2**
1. Phase 1 — Bid-specific question #7 (re-bid vs separate package). Confidence below 60% → flagged for Rocky.
2. Phase 6 — External submission authorisation (hard case 6, mandatory).

Plus the optional Phase 4 envelope-comparison review (could be silent if inside envelope; dry-run had a low-confidence envelope which Rocky may glance at without action).

If Phase 1 #7 had been auto-decided ≥60% (e.g. via a §13.X rule or a stronger precedent), total touchpoints = **1** (just Phase 6 send authorisation).

Compare to pre-v2 baseline: ~6 questions during Phase 1 + ongoing decisions throughout = ~10–15 Rocky touchpoints per bid.

**Reduction: ~85% fewer touchpoints in this scenario.** Aim for 95% reached on the auto-decide-#7 case.

## What worked

- **Priority chain auto-decided 6 of 7 questions** at ≥70% confidence each.
- **Handoff bus protocol verified** in Build 2 round-trip test (4/4 PASS).
- **Daemon code is clean stdlib Python** — runs anywhere with Python 3.11+.
- **Envelope skill produced a usable comparison** even on a small bid with no public contract disclosure (low-confidence is acknowledged, not hidden).
- **Lifecycle skill spec is comprehensive** — covers Phases 1→7 + failure modes + worked example.

## What didn't work / honest gaps

- **Web research yielded no specific contract value** for Solutions Plus's Hornsby slice → envelope confidence dropped to 35%, below the 60% threshold for actionable comparison. This is the right behaviour (confidence honest), but it means the envelope sanity-check is mostly null on small private subs.
- **Bid-specific question #7** (re-bid vs separate package) couldn't be auto-decided because the patterns aren't codified yet — it's an HC-relationship question, not a scope/site/rate question. Future v2 work: add HC-relationship auto-decision rules to §13 once 3+ similar cases land.
- **Daemon ntfy POST not live-tested from sandbox.** Network egress blocked. Real test happens on Rocky's first daemon launch.
- **lfp terminal not active in this dry-run** → pricer responses stubbed. End-to-end live test requires both terminals + daemon running. Recommend Rocky run a real 2632 / next-bid live trial before depending on the system for a high-value submission.
- **Phase 3.5 + Phase 4 parallelism** is designed but not stress-tested. v1 runs them sequentially in this dry-run.

## Recommended live-trial protocol

When the next live bid lands:
1. Start daemon: `python Codebase/lfcs-orchestrator/daemon/lfo_handoff_daemon.py` in a third terminal (or background via `Start-Process -WindowStyle Hidden`).
2. Subscribe to ntfy topic `rocky-lfcs-in76m24d` from phone.
3. Open lfo + lfp terminals.
4. In lfo: `start bid {job-id} from {inbound-path}`.
5. Walk away. Check phone for notifications.
6. Return to lfo when notified for review gate; lfp when notified to "check handoff."
7. After Phase 7 close, review `_Brain/_Log.md` entry + lessons written.

If the system stalls or produces nonsense at any point, type `abort bid` in lfo terminal — orchestrator clears state and surfaces what went wrong.

## Final dry-run state cleanup

state.json reset to `active_bid_id=null, current_phase=null, rocky_gate_active=false` (no real bid was active).
No real artefacts created. No Airtable writes. No external sends.
This file (`2631-dry-run-self-test-2026-05-08.md`) is the self-test report.
