---
purpose: Self-evaluation of lfcs-orchestrator v1 against the four real-world 2630 gaps. Establishes acceptance bar for v1 + identifies any gap not yet covered.
authored_by: claude-code-orchestrator
created: 2026-05-08
session_type: self-evaluation
target: orchestrator v1 (CLAUDE.md + 6 skills + standards + lessons-learned + alias)
---

# Self-Evaluation — Orchestrator v1 vs 2630 Gaps

The 2630 session surfaced 4 gaps. The orchestrator v1 is acceptable only if it would have caught each gap BEFORE it reached the worker's first-pass output.

## Acceptance bar

For each 2630 gap, three checkpoints:
1. **Catch point** — which orchestrator phase + skill catches it
2. **Mechanism** — what mechanism (gate / pattern rule / standing context / library)
3. **Failure mode** — what would have to break for the orchestrator to miss it

If catch point is **Phase 1 or Phase 2** (pre-worker): full pass.
If catch point is **Phase 3 first-pass-prompt-time** via gap-watch correction: pass with note (caught after worker prompt drafted, before worker runs).
If catch point is **Phase 4 sanity-check** via override capture: fail (gap reached worker output uncorrected; depends on Rocky catching).

---

## Gap 1 — Standard LFCS exclusions not applied

**Original miss:** Worker built exclusions per-job from generic methodology rows. ~$97k of always-out items baked into first-pass.

| Checkpoint | Verdict |
|---|---|
| Catch point | **Phase 2** — `lfo-standard-exclusions-apply` runs BEFORE first-pass prompt is drafted |
| Mechanism | `standards/Standard-LFCS-Exclusions-Library.md` (49 items, 5 categories) + skill walks Rocky in 5 batches + gap rule G1 blocks first-pass prompt if exclusions skeleton absent |
| Failure mode | Phase 2 skipped (Rocky goes "skip exclusions, just price"). Mitigation: gap rule G1 is a `severity: block` rule — orchestrator refuses to relay first-pass prompt without skeleton existing on disk. |

**Verdict:** ✅ **Full pass** — caught Phase 2 before worker drafts anything.

---

## Gap 2 — Site exposure category not confirmed

**Original miss:** Worker assumed tidal from drawing-spec marine cement + stainless reo. Site is coastal-air. Worker carried saltwater +5% uplift, tidal-window scheduling, tidal-marine productivity.

| Checkpoint | Verdict |
|---|---|
| Catch point | **Phase 1** — intake gate Q-2 mandatory single-select (immersed/tidal/coastal-air/inland) |
| Mechanism | `intake-gate-questions.md` Q-2 + envelope `site_exposure` field + gap rule G2 strips tidal/saltwater inferences from any worker output that says otherwise |
| Failure mode | Rocky answers Q-2 wrong (says tidal when site is coastal-air). Orchestrator can't catch that — Rocky's call stands. But the inverse (worker invents tidal from drawing-spec when Rocky said coastal-air) is caught by G2. |

**Verdict:** ✅ **Full pass** — caught Phase 1 with mandatory Rocky-input.

---

## Gap 3 — Labour rate not confirmed

**Original miss:** Worker applied $85/hr Rate Card V1.7 day rate. Rocky locked $95/hr blended.

| Checkpoint | Verdict |
|---|---|
| Catch point | **Phase 1** — intake gate Q-3 mandatory (default $95/hr or override) |
| Mechanism | `intake-gate-questions.md` Q-3 + envelope `labour.blended_rate_aud_per_hr` field + gap rule G3 strips $85 / Rate-Card-V1.7-day references from worker output if envelope says different |
| Failure mode | Rocky enters wrong rate at Q-3. Orchestrator can't validate Rocky's input — that's a Rocky-input layer. |

**Verdict:** ✅ **Full pass** — caught Phase 1 with mandatory Rocky-input.

---

## Gap 4 — Margin and contingency build-up rules

**Original miss:** Worker applied 1.165 / 1.10 instead of locked formula (labour 1.10×1.15 = 1.265; materials 1.15×1.10 = 1.265). Per-category ordering preserved.

| Checkpoint | Verdict |
|---|---|
| Catch point | **Phase 1** — intake gate Q-4 mandatory (default formula or override) |
| Mechanism | `intake-gate-questions.md` Q-4 + envelope `margin_contingency` block (per-category: contingency_pct, margin_pct, sequence) + standing-context §4 documents formula explicitly + gap rule G4 flags wrong-multiplier output and inserts locked formula |
| Failure mode | Worker mis-applies envelope despite explicit instructions. Phase 3 first-pass prompt (`lfo-prompt-pricing` step 5) literally writes the formula inline: "Labour: direct × 1.10 cont × 1.15 margin (cont-then-margin) = 1.265 loaded; Materials: direct × 1.15 margin × 1.10 cont (margin-then-cont) = 1.265 loaded. Same final 1.265, distinct ordering per category. Show direct AND loaded views per line on internal output." Hard to mis-apply. |

**Verdict:** ✅ **Full pass** — caught Phase 1 with mandatory Rocky-input + Phase 3 explicit formula in worker prompt.

---

## Summary table

| Gap | Catch point | Skill | Verdict |
|---|---|---|---|
| G1 — Standard exclusions | Phase 2 | `lfo-standard-exclusions-apply` | ✅ Pass |
| G2 — Site exposure | Phase 1 | `lfo-intake-gate` Q-2 | ✅ Pass |
| G3 — Labour rate | Phase 1 | `lfo-intake-gate` Q-3 | ✅ Pass |
| G4 — Margin/contingency | Phase 1 | `lfo-intake-gate` Q-4 | ✅ Pass |

**Result:** all 4 gaps caught before worker first-pass output. Orchestrator v1 acceptance bar met.

---

## Coverage gaps identified during self-eval

1. **No mechanism to validate Rocky's intake answers against drawing-spec contradiction.**
   Example: Rocky answers Q-2 = `tidal` but drawings clearly show slab above MHW. Orchestrator currently logs the contradiction in session but proceeds with Rocky's answer. Should it surface and ask once? Currently designed to not — Rocky's call stands.
   **Decision:** stand. Rocky's call always wins. Orchestrator logs distinctions but doesn't override Rocky-input. Otherwise it becomes a different agent.

2. **No mechanism to retry worker if it ignores the envelope.**
   If worker output uses $85 despite envelope saying $95, gap-watch G3 fires. Orchestrator strips + re-prompts. But if worker keeps regenerating with $85 (e.g. methodology row stuck): G3 fires repeatedly. After 3 fires on the same rule in same session: orchestrator escalates to Rocky.
   **Decision:** add to `lfo-gap-watch` SKILL.md as "3-strike escalation" rule. (Will fix below.)

3. **No mechanism for Rocky to mid-session change a locked field.**
   Q-3 locked $95 at intake; mid-session Rocky says "actually use $90 for this scope." Orchestrator currently re-runs envelope rebuild. Should flag any prior worker output as superseded. Currently `lfo-prompt-pricing` says it does this in failure-modes section.
   **Decision:** stand. Already covered.

4. **Standard Exclusions Library v1 is a 3-job reconstruction.**
   Library may have wording variants the worker pushes back on. That's expected — first 3 sessions should refine wording via the lessons-write proposals queue. `methodology_status: v1-reconstruction` flagged in frontmatter.
   **Decision:** stand. Refinement is expected.

---

## Action items from self-eval

1. Add 3-strike escalation rule to `lfo-gap-watch` (next revision).
2. Run on first real bid; expect rapid library expansion.
3. Re-evaluate after 3 sessions — re-run this self-eval table against new gaps surfaced.

---

## Conclusion

Orchestrator v1 ready to run on next bid. Acceptance bar (all 4 known 2630 gaps caught pre-worker-output) met. One coverage refinement pending (3-strike escalation in gap-watch). All other observations are expected v1 limits.
