# Rfp Reverse Engineer

> Reverse-engineers a federal RFP we received — given the SOW/PWS and evaluation criteria already in the Theseus KG, reconstructs the CO's hidden decision tree (upstream `sow-pws-builder` 6 scope blocks + 3 intake answers), surfaces hot buttons, ghost language, discriminator hooks, missing-section signals, and CPFF-form / Section-5 / QASP / Key-Personnel traps. USE WHEN the user asks "what scope decisions did the CO already make?", "reverse engineer this RFP", "what hot buttons are hiding in this PWS?", "where are the discriminator hooks?", "did they pick CPFF completion or term form?", "anything suspiciously missing?", or any variant of decoding CO intent. Pulls `requirement`, `deliverable`, `proposal_instruction`, `evaluation_factor`, `clause`, `performance_standard` from the active workspace KG and emits a JSON envelope feeding `proposal-generator`. DO NOT USE FOR proposal prose (`proposal-generator`), pricing (`price-to-win`), clause audit (`compliance-auditor`), or sub SOW (`subcontractor-sow-builder`).

- Skill: `bdm-15/rfp-reverse-engineer` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add bdm-15/rfp-reverse-engineer`
- Raw SKILL.md: https://api.skillmd.com/api/skills/bdm-15/rfp-reverse-engineer/raw
- Safety review: PASS (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- License: MIT
- Author: BdM-15 (https://skillmd.com/u/bdm-15)
- Updated: 2026-08-19
- Page: https://skillmd.com/skills/bdm-15/rfp-reverse-engineer

---

# RFP Reverse-Engineer

## Capture-insights adapter (no KG)

**Run** from Agent Skills or chat ("reverse engineer this RFP") — contractor lens, not CO advice.

Inspired by [1102tools SOW/PWS Builder](https://1102tools.com/tools) **stance inversion**: the 1102 skill walks a CO forward through intake → scope blocks → SOW; this skill runs the same decision tree **backwards** from solicitation text in your pursuit vault.

- **Deterministic scan:** ghost language, missing sections, contract-type cues, discriminator hooks from Studio markdown (`02_intel/rfp_reverse_engineer.json` + `.md`).
- **Context:** Pipeline row + pursuit workspace files — never invent RFP text.
- **Optional LLM:** strategist read when smart model is on; citations must stay on vault paths.
- **Handoff:** `proposal-generator`, `compliance-auditor`, `ptw-analysis`.


You are a senior capture-side intelligence analyst working multi-turn against the active Theseus workspace knowledge graph. Given an RFP, SOW, PWS, or task-order solicitation **we received**, reconstruct the **contracting officer's hidden decision tree** — the same 3 acquisition-strategy intake answers and 6 scope decision blocks the upstream `sow-pws-builder` skill walks a CO through, but inferred BACKWARDS from the document the CO actually published.

## When to Use

- "What scope decisions did the CO already make on this RFP?"
- "Reverse engineer the SOW — what was their thinking?"
- "Where are the hot buttons hiding in this PWS?"
- "What discriminator hooks does the evaluation criteria open up?"
- "Did the CO pick CPFF completion or term form?"
- "Is anything suspiciously missing from this solicitation?"
- "What ghost language is hiding in Section M?"

## The Stance Inversion (READ THIS FIRST)

The upstream `sow-pws-builder` skill walks a **federal contracting officer** FORWARD through 3 intake questions and 6 decision blocks until a 14-section SOW/PWS falls out. The output is the document.

**This skill runs the same machine BACKWARDS from the bidder's seat.** The document is the input. The reconstructed decision tree is the output. Every section of the SOW/PWS the CO published encodes a scope decision they already made — and often a scope decision they DIDN'T make and are quietly leaving open. The `subcontractor-sow-builder` companion skill is the forward inverse (prime writes SOW for sub).

| Concept                                | Upstream (CO writing)                                                | This skill (bidder reading)                                                                                                                                                     |
| -------------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Direction                              | Decisions → document                                                 | Document → inferred decisions                                                                                                                                                   |
| Output                                 | 14-section .docx                                                     | JSON envelope: `inferred_intake`, `decision_tree`, `hot_buttons`, `discriminator_hooks`, `ghost_language`, `missing_sections`, `cpff_form_signal`, `key_personnel_clause_check` |
| Section 14 (Constraints & Assumptions) | Where the CO documents derived defaults for the CO's own audit trail | Where the CO is most likely to leak intent — read it first                                                                                                                      |
| QASP Payment Consequence column        | Pre-committed by CO                                                  | Tells us where the CO has highest performance anxiety → discriminator opportunity                                                                                               |
| Missing Section 5                      | CO chose FFP or CR (no T&M ceiling)                                  | Confirms cost-risk allocation                                                                                                                                                   |
| FAR 52.237-2 cited for Key Personnel   | CO error (clause is "Protection of Buildings")                       | Capture flag — CO contracts shop is sloppy → likely amendments coming                                                                                                           |

## Operating Discipline

- **No invention.** Every inferred decision cites the source chunk(s) or entity(ies) in the KG. If the document is silent, mark the decision as `inferred=false, status=open` and surface it as a clarification question for the proposal team.
- **Workspace-first.** All reasoning anchors on entities and chunks already in the active Theseus KG. Use `kg_entities` and `kg_chunks`.
- **Format-agnostic input.** UCF Section L/M, FAR 16 task order, FOPR, BPA call, OTA, agency-specific format — they all map to the same 14-section spec when reverse-flowed. If sections are reordered or merged, normalize silently.
- **Cite signals, not guesses.** Every entry in `hot_buttons`, `discriminator_hooks`, `ghost_language` must cite the chunk_id or entity_id that triggered the inference + the matching pattern from `references/rfp_signal_patterns.md`.

## Citation Discipline for the Narrative (CRITICAL — read before step 10)

The JSON envelope (steps 4–9) carries `source_chunk_ids[]` on every entry. The **prose narrative** (step 10) is where models reliably drop citations and downgrade to flat assertions. This section exists to prevent that.

**Two classes of sentences. Treat them differently.**

### Class A — Factual anchors (MUST cite)

Any sentence that asserts what the RFP says, what the CO chose, what the KG contains, what a clause cites, what a deliverable threshold is, or any specific number / proper noun lifted from the workspace.

**Rule:** End the sentence (or the relevant clause) with `[chunk-xxxx]` (or `[chunk-xxxx, chunk-yyyy]` when 2–3 chunks support it). If the fact came from a `kg_entities` call rather than a chunk, use `[entity: <Name>]`. If it came from a `references/...` bundle file you read, use `[per references/<file>.md]`.

Class A examples that the audit currently flags as unsourced — fix them like this:

| Bad (flat assertion)                                                                                 | Good (anchored)                                                                                                                                                                |
| ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| "FFP Task Order under AFCAP V IDIQ."                                                                 | "FFP Task Order under AFCAP V IDIQ [chunk-3a2f]."                                                                                                                              |
| "Attachment 1 uses AQL-style thresholds (95% operational equipment, zero discrepancies on escorts)." | "Attachment 1 uses AQL-style thresholds (95% operational equipment, zero discrepancies on escorts) [chunk-7b91, chunk-7b92]."                                                  |
| "Active KG contains ~400 entities heavy on `requirement` and `performance_standard`."                | "Active KG slice (per the `kg_entities` call above) contains ~400 entities heavy on `requirement` and `performance_standard`."                                                 |
| "Block 1 (Mission/Service Model): Locked on single-site OCONUS ISS at ADAB/380 ECES."                | "Block 1 (Mission/Service Model): Locked on single-site OCONUS ISS at ADAB/380 ECES [chunk-1c44] — see `decision_tree_reconstruction.block_1` in the JSON for full citations." |

For the narrative, when you're summarizing a JSON section that already carries N citations, you may write `[see decision_tree.block_1 source_chunk_ids]` instead of repeating 6 chunk ids inline.

### Class B — Reasoning leaps (DO NOT strip; frame visibly)

Your judgment about what a signal _means_ for our capture posture, the proposal team's playbook, capture-side patterns, or what is "likely" to come next. These are not facts in the RFP — they're you reasoning on top of the facts.

**Rule:** Do not strip these. Frame them with a visible-judgment marker so a reader (and the audit) can tell it's a reasoning leap, not an unsourced fact:

- "In our capture experience, …"
- "A defensible read is that …"
- "This is the classic … pattern — …"
- "Likely the CO will …"
- "Our read: …"
- "Rule of thumb on OCONUS Air Force ISS recompetes: …"
- "The CO's posture here would overstate … if …"

Class B examples — keep these as-is, do **not** add `[chunk-xxxx]`:

- "Our read: this is a price-disciplined recompete with the incumbent already inside the building."
- "Likely the CO will issue an amendment to fix the FAR 52.237-2 trap before close."
- "Classic OCONUS ISS pattern — high QASP density signals their performance anxiety, not yours."

The audit tool now exempts visible-judgment framing from the grounding denominator. **Do not** dress up Class A facts in Class B language to dodge the audit — it's transparent and it produces a worse brief.

## Workflow Checklist

Execute in order. Record each inference + source citation in the run transcript.

### 1. Pull workspace context

Call `kg_entities`:

```json
{
  "types": [
    "solicitation",
    "document_section",
    "requirement",
    "deliverable",
    "proposal_instruction",
    "evaluation_factor",
    "subfactor",
    "clause",
    "performance_standard",
    "transition_activity",
    "government_furnished_item",
    "labor_category",
    "contract_line_item",
    "period_of_performance",
    "place_of_performance",
    "regulatory_reference",
    "amendment"
  ],
  "limit": 400
}
```

Then `kg_chunks` for any explicit references the user mentions ("the SOO paragraph about FedRAMP", "Section M.4 evaluation language").

### 2. Infer the 3 acquisition-strategy intake answers

Load `references/reverse_engineering_catalog.md` Section A. For each:

| Intake Question               | Backwards-inference signal                                                                                                                                               |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| SOW or PWS?                   | Section 3 phrasing — task-oriented "shall perform" → SOW; outcome-oriented "shall achieve / maintain" → PWS                                                              |
| Contract type?                | Presence of Section 5 ceiling-hours table → T&M/LH; CPFF form citation in Section 1.1 → CR; absence of either + FFP language → FFP; CLIN structure (if visible) confirms |
| Commercial or non-commercial? | FAR 52.212-4 cite or "commercial item" language → Part 12; full Section I/L buildout → Part 15                                                                           |

Record as `inferred_intake_answers` with `signal` (the pattern matched), `source_chunk_ids[]`, `confidence` ("high" / "medium" / "low" / "open").

### 3. Reverse-walk the 6 scope decision blocks

For each Block 1–6, load the corresponding row of `references/reverse_engineering_catalog.md` Section B. For each decision in the block, check:

- **Decision visible** → record what the CO chose + source chunk.
- **Decision implied** → record the inference rule that fired + source chunk.
- **Decision absent (open)** → record as a `clarification_question` for the proposal team to surface in Q&A.

Output structure: `decision_tree_reconstruction.block_1` through `block_6`, each containing the upstream questions with `co_choice`, `derivation_signal`, `source_chunk_ids[]`, `status` ("locked" / "implied" / "open").

### 4. Surface hot buttons

Load `references/reverse_engineering_catalog.md` Section C (Hot-Button Decoder). For each pattern that fires in the KG, emit a `hot_buttons[]` entry:

```json
{
  "id": "HB-001",
  "label": "24/7 coverage stated without surge multiplier",
  "implication": "CO knows this is staffing-heavy; unit cost discipline will drive evaluation.",
  "section_origin": "PWS Section 3.4",
  "source_chunk_ids": ["chunk_47"],
  "discriminator_opportunity": "Propose tiered-coverage model with surge automation that flexes from 24/7 down to follow-the-sun for low-volume periods."
}
```

### 5. Surface discriminator hooks

Load `references/discriminator_hooks.md`. For each evaluation factor / subfactor in the KG, check for hook patterns ("most highly rated", "preferred but not required", "where past performance demonstrates"). Emit `discriminator_hooks[]`:

```json
{
  "id": "DH-001",
  "evaluation_factor": "Technical Approach",
  "hook_phrase": "exceptional past performance in classified cloud migrations",
  "hook_type": "ghost_preference",
  "source_chunk_ids": ["chunk_112"],
  "proposal_play": "Lead the Technical Approach narrative with the [past_performance_reference] for the DoD IL5 migration; tie it to Win Theme #2."
}
```

### 6. Detect ghost language

Load `references/rfp_signal_patterns.md` Section D (Ghost Language Catalog). Match patterns like "shall consider", "as appropriate", "where applicable", "may include but is not limited to", undefined acronyms, evaluation factors with no measurable threshold, "best practices" without a cited standard. Emit `ghost_language[]`:

```json
{
  "id": "GL-001",
  "phrase": "as appropriate",
  "section_origin": "SOW Section 3.7",
  "risk": "Requirement is non-measurable; CO retains unilateral discretion.",
  "source_chunk_ids": ["chunk_88"],
  "recommended_action": "Submit Q&A asking the CO to define the trigger; if unanswered, document the assumed interpretation in the proposal."
}
```

### 7. Detect missing-section signals

Walk the 14-section reference list. For each section the document lacks, emit a `missing_sections[]` entry with the inferred reason:

| Section absent                                                          | Likely meaning                                                                                                   |
| ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| Section 5 (Labor Category Ceiling Hours)                                | Contract is FFP or CR (not T&M / LH).                                                                            |
| Section 9 Security Requirements (when classified work implied)          | CO has not yet issued DD Form 254 — capture should ask Q&A.                                                      |
| Section 13 Transition (incumbent recompete with no transition language) | Suspicious — likely amendment incoming OR CO accepts incumbent advantage.                                        |
| Section 14 Constraints & Assumptions                                    | CO did not document derived defaults — proposal should over-document its own assumptions to lock interpretation. |

### 8. Run targeted compliance traps

Load `references/far_citations.md` Section E (Trap Detector). Check the `clause` entities for known traps:

- **FAR 52.237-2 cited for Key Personnel substitution** → `key_personnel_clause_check.status = "incorrect"` (clause is "Protection of Buildings"). Flag as a CO error → likely amendment.
- **CPFF cited without (d)(1) or (d)(2)** → `cpff_form_signal.status = "ambiguous"` (CO has not committed completion vs term form) → mandatory Q&A question.
- **QASP Payment Consequence column = CPARS rating language** → `qasp_cpars_check.status = "non-compliant"` (CPARS is FAR 42.15 post-performance, not QASP-bindable) → CO error → propose corrected QASP language as a soft amendment in Q&A.

### 9. Assemble the JSON envelope

```json
{
  "opportunity_context": {"solicitation_id": "...", "agency": "...", "naics": "...", "psc": "..."},
  "inferred_intake_answers": {
    "sow_or_pws": {"value": "PWS", "signal": "Section 3 outcome-oriented verbs", "source_chunk_ids": ["..."], "confidence": "high"},
    "contract_type": {"value": "FFP", "signal": "No Section 5; FAR 16.202 cited", "source_chunk_ids": ["..."], "confidence": "high"},
    "commercial_status": {"value": "non-commercial", "signal": "Full Section I/L buildout, FAR Part 15", "source_chunk_ids": ["..."], "confidence": "medium"}
  },
  "decision_tree_reconstruction": {
    "block_1_mission_service_model": [...],
    "block_2_technical_scope": [...],
    "block_3_scale_volume": [...],
    "block_4_organizational_scope": [...],
    "block_5_contract_structure": [...],
    "block_6_quality_oversight": [...]
  },
  "hot_buttons": [...],
  "discriminator_hooks": [...],
  "ghost_language": [...],
  "missing_sections": [...],
  "cpff_form_signal": {"status": "completion|term|ambiguous|n/a", "source_chunk_ids": [...]},
  "key_personnel_clause_check": {"status": "correct|incorrect|absent", "clause_cited": "...", "recommended_clause": "..."},
  "qasp_cpars_check": {"status": "compliant|non-compliant|absent", "source_chunk_ids": [...]},
  "clarification_questions": [...],
  "citations": {
    "kg_entities": [...],
    "kg_chunks": [...],
    "far": ["37.102(d)", "37.602", "16.306(d)", "..."]
  },
  "claim_gaps": [
    "Section 9 absent but FedRAMP IL5 implied — CO has not issued DD 254."
  ]
}
```

Write to `{run_dir}/artifacts/rfp_reverse_engineering.json` via `write_file`.

**⚠️ Steps 10–12 below are REQUIRED.** The JSON envelope is for the downstream `proposal-generator` skill. The capture team also needs the human-readable narrative — do not stop the run after `write_file`.

### 10. (Optional) Load the bullet template

If you find yourself reaching for paragraph prose or losing track of which bullets carry anchors, optionally call `read_file({"path": "references/narrative_template.md"})` for a strict bullet skeleton you can fill in literally. The template is a low-degree-of-freedom fallback for runs where the model is drifting toward unsourced paragraph synthesis. **It is no longer mandatory** — a senior capture analyst writes naturally in their own voice with citation discipline; the template exists as a guardrail, not a cage.

### 11. Render the narrative in your natural capture-analyst voice

Write the brief the way a senior capture lead would — short paragraphs and bullets are both fine, mix them as the material demands. The discipline is **citation, not format**:

- **Class A** (factual lift from the workspace): cite the source. Acceptable anchors are `[chunk-xxxx]`, `[entity: <Name>]`, `[per references/<file>.md]`, `[see <jsonpath>.source_chunk_ids]`, **or** the natural document-section identifier the CO uses (`H.3`, `H.1.4.6.1.1`, `Section M.4`, `Attachment J-1`, `CDRL A001`, `FAR Part 45`, `DAFI 36-2903`, `MIL-STD-810H`). The audit credits any of these.
- **Class B** (your judgment, capture vernacular): frame visibly. Acceptable openers are `Our read:`, `Play:`, `Sweet spot:`, `Hot button:`, `Hook:`, `Theme:`, `Discriminator:`, `Ghost:`, `Risk:`, `Trap:`, `Signal:`, `Pattern:`, `Read:`, `In our capture experience…`, `Likely the CO will…`, `Classic … pattern —`, `Rule of thumb:`. Or the equivalent embedded mid-sentence: `the CO has clearly …`, `signals X`, `smells like a Y`, `worth a bet`, `means our price-to-win must …`, `will drive Z strategy`, `raises risk of W`.

**Do not** dress up Class A facts in Class B language to dodge the audit — it's transparent and it produces a worse brief. **Do not** invent citations. If a bullet has neither a workspace anchor nor a visible-judgment marker and is not actually a recommended action / capture-deliverable handoff (e.g. "Update the win-theme spine," "Submit the six clarification questions"), drop it. A shorter brief is fine.

### 12. Self-audit before returning

Mentally walk every paragraph and bullet:

1. Does it assert a fact about the workspace? It needs an anchor — chunk id, entity tag, document section identifier, or regulatory citation.
2. Does it express your judgment / read / play / pattern recognition? It needs a visible-judgment marker so a reader (and the audit) can tell it's reasoning, not unsourced fact.
3. Is it a recommended next-step action or capture-deliverable handoff? Phrase it that way (`Submit the …`, `Update the …`, `Feed this envelope into …`) — these are credited as cover-note actions, not domain claims.
4. Headings (`#`, `##`) and code fences are exempt.

If a line fits none of those four shapes, rewrite or drop it. **Do not** invent chunk ids. The grounding-ratio audit (`tools/audit_skill_grounding.py`) enforces ≥0.50 for this skill.

## What This Skill Does NOT Cover

- **Drafting proposal prose / win themes / FAB chains** → use `proposal-generator` (it consumes this skill's JSON envelope).
- **Pricing / cost stack** → use `price-to-win`.
- **FAR clause compliance audit** (existence checks, amendments since solicitation issued) → use `compliance-auditor` (eCFR MCP).
- **Black-hat competitor research** → use `competitive-intel` (USAspending MCP).
- **Writing the prime↔sub SOW** → use `subcontractor-sow-builder`.
- **Inventing facts the document does not support.** Every inference must cite a chunk or entity. Open decisions become Q&A questions, not fabrications.

## References

- [references/narrative_template.md](references/narrative_template.md) — **Optional** strict bullet skeleton for the step-11 narrative. Use as a fallback when the run is drifting toward unsourced paragraph synthesis; not loaded by default in v0.5.0+.
- [references/reverse_engineering_catalog.md](references/reverse_engineering_catalog.md) — Section A (3 intake-question backwards-inference table), Section B (6 scope-block reverse-walk patterns), Section C (Hot-Button Decoder).
- [references/discriminator_hooks.md](references/discriminator_hooks.md) — Discriminator-hook pattern catalog: ghost preferences, "most highly rated" cues, past-performance unlock phrases, FAB-chain trigger language.
- [references/rfp_signal_patterns.md](references/rfp_signal_patterns.md) — Section D (Ghost Language Catalog), missing-section signal table, contract-type detection patterns, security-tier escalation cues.
- [references/far_citations.md](references/far_citations.md) — FAR sections this skill cites; Section E Trap Detector (52.237-2, CPFF form ambiguity, QASP↔CPARS mistake, FAR 16.601(c)(2) ceiling-hour omission).

