{"slug":"bid-evaluator","title":"bid-evaluator","summary":"Evaluate tabulated subcontractor bids against specs and drawings — scope gap analysis, exclusion risk scoring, award recommendation. Triggers: 'evaluate bids', 'bid evaluation', 'lowest responsible bidder'.","platform":"Claude","tags":[],"authorName":"LLM Mart","authorSlug":"llm-mart","score":0,"source":"github","price":null,"verified":false,"createdAt":"2026-10-19T21:17:02.01998Z","repo":{"url":"https://github.com/dleerdefi/claude-code-construction","stars":44,"forks":13,"license":"MIT","updatedAt":"2026-10-18T06:12:41Z"},"bodyHtml":"<hr>\n<h2>name: bid-evaluator\ndescription: &gt;\nEvaluate tabulated subcontractor bids against specs and drawings — scope\ngap analysis, exclusion risk scoring, award recommendation. Triggers:\n'evaluate bids', 'bid evaluation', 'lowest responsible bidder'.\nargument-hint: \"&lt;tabulated_bids_dir&gt; [scope_description]\"\ndisable-model-invocation: true</h2>\n<h1>Bid Evaluator</h1>\n<p>Evaluate tabulated subcontractor bids against construction documents.\nThis skill does NOT make the award decision — it builds the analytical\nfoundation so the PE/PM can decide quickly and confidently.</p>\n<h2>Pipeline &amp; Disambiguation</h2>\n<pre><code>/bid-tabulator → THIS SKILL → user confirms → /subcontract-writer\n</code></pre>\n<p><strong>This skill requires tabulated bids as input.</strong> If the user has raw bid PDFs that haven't been tabulated yet, stop and ask them to run <code>/construction:bid-tabulator</code> first; it is user-invoked only, so you cannot start it from here. It produces the per-bidder JSON files and comparison Excel that this skill consumes.</p>\n<ul>\n<li>User has <strong>bid PDFs</strong> → ask them to run <code>/construction:bid-tabulator</code> (data capture), then <code>/construction:bid-evaluator</code></li>\n<li>User has <strong>tabulated bids</strong> and wants analysis → this skill directly</li>\n<li>User says \"compare bids\" or \"buyout\" → check if bids are already tabulated; if not, ask them to run <code>/construction:bid-tabulator</code> first</li>\n</ul>\n<h2>Tier System</h2>\n<ul>\n<li><strong>RIGID</strong>: Output schema, scoring tables, file naming</li>\n<li><strong>GUIDED</strong>: Dialogue sequencing, scope assembly, scoring thresholds</li>\n<li><strong>FLEXIBLE</strong>: Bid interpretation, scope coverage, risk assessment</li>\n</ul>\n<h2>Required Inputs</h2>\n<ol>\n<li>Tabulated bids (from /bid-tabulator or equivalent)</li>\n<li>Relevant specification sections</li>\n<li>Relevant drawing sheets (Claude reviews via vision)</li>\n<li>Scope context (from user dialogue)</li>\n</ol>\n<p>Optional: bid form/ITB, schedule, owner requirements, budget estimate,\npast experience with bidders.</p>\n<hr>\n<h2>Step 1: Scope Assembly</h2>\n<p><strong>Complete before analyzing any bids.</strong></p>\n<h3>Mode Detection</h3>\n<p>Read <code>.construction/project.yaml</code> at the project root: present and readable means AgentCM mode (note its <code>contract_version</code>), absent means flat-file mode. A listing that shows the file does not decide it: read it.</p>\n<ul>\n<li><strong>AgentCM mode</strong>: Read each spec section from <code>.construction/specs/&lt;section&gt;.txt</code> (<code>09 65 13</code> is <code>09-65-13.txt</code>; each line starts with its page), listed in <code>.construction/INDEX.md</code>: it is the section's text, and a section's pages are never extracted again from the PDF. Never run <code>pdf_text.py</code> or <code>rasterize_page.py</code> on a section's pages: not to check them, and not inside a page range (<code>--pages 1,2</code> where page 2 is a section is one). A read manual's pages in no section (INDEX.md lists them) are read in the PDF, those pages only (<code>--pages</code>). Only for a manual INDEX.md lists under \"Spec manuals not read\", read spec-splitter's <code>.construction/skills/spec_text/</code> instead. Use sheet index from <code>.construction/index/sheet_index.yaml</code> for drawing identification. Follow <code>${CLAUDE_PLUGIN_ROOT}/reference/agentcm-mode.md</code>: which source wins, what a missing file or an empty search means, which file answers what, drawings through <code>crop.sh</code>, sheet ids, and how to record a correction of AgentCM's data.</li>\n<li><strong>Flat File mode</strong>: Discover spec PDFs via <code>CLAUDE.md</code> paths or directory search (<code>Specifications/</code>, <code>Specification Sections/</code>). Read drawing sheets directly from PDF.</li>\n</ul>\n<h3>1a. Spec Review</h3>\n<p>Extract from each spec section: work included (Parts 1-3), work by\nothers (GC/NIC/Owner), related section cross-references, performance\nrequirements, coordination and temporary requirements.</p>\n<p>This step is never skipped. The spec sections are the baseline that\nSILENT is measured against; a scope sheet lists sections, not their\nrequirements, and \"no drawing review\" does not mean \"no spec review\".\nIn flat-file mode dump each section's text (TEXT pages in the dump are\nread as text; rasterize VISION pages):</p>\n<pre><code>\"${CLAUDE_PLUGIN_ROOT}/bin/construction-python\" \"${CLAUDE_PLUGIN_ROOT}/scripts/pdf/pdf_text.py\" \"{section.pdf}\"\n</code></pre>\n<p>Take the output directly, or, to search a dump more than once, save it with\n<code>--output \".construction/skills/bid-evaluator/text/&lt;section&gt;.txt\"</code>, never in\n<code>/tmp</code> or any other folder outside the project.</p>\n<h3>1b. Drawing Review</h3>\n<p>Load <code>references/drawing-review.md</code> for guidance on what to look for\nper drawing type. Vision-read key sheets to identify scope items,\nconditions, and quantities not apparent from specs. Track drawing-\nderived items separately — they differentiate thorough bidders.\nOffload reference after completing drawing review.</p>\n<h3>1c. User Dialogue</h3>\n<p>Ask targeted questions to fill gaps documents can't answer. Do not\ndump a questionnaire — ask conversationally, skip what you already\nknow.</p>\n<p><strong>Always ask:</strong> package definition (which specs/drawings), GC-provided\nitems, bid count and format, drawing confirmation if provided.</p>\n<p><strong>Ask when relevant:</strong> multi-trade splits, alternates/allowances,\nqualification requirements, budget reference, schedule constraints.</p>\n<p>Confirm assembled scope with user before proceeding.</p>\n<h3>1d. Build Scope Baseline</h3>\n<p>Produce internal baseline document: items in sub scope (with source),\ndrawing-identified scope, GC/owner exclusions, allowances, alternates,\nqualifications, schedule constraints.</p>\n<hr>\n<h2>Step 2: Bid Analysis</h2>\n<p>Load <code>references/buyout-domain.md</code> for domain knowledge on bid\nlanguage interpretation, common scope splits, red flags, trade-\nspecific evaluation notes, and non-price factors. Keep loaded\nthrough Steps 2a-2d, then offload.</p>\n<h3>2a. Normalize Pricing</h3>\n<pre><code>Adjusted Base = Submitted Base\n              + Excluded spec-required items\n              - Included GC-provided items\n              + Accepted alternates ± Allowance adjustments\n</code></pre>\n<p>Valuation order: other bidder's line item → budget estimate → professional\njudgment (flagged) → qualitative risk if unknown.\nDocument every adjustment. No silent price changes.\nFlag unit price outliers (&gt;2x median). Calculate exposure ranges.</p>\n<h3>2b. Scope Coverage Mapping</h3>\n<p>Map each bidder against every scope baseline item using five statuses:</p>\n<table>\n<thead>\n<tr>\n<th>Status</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>INCLUDED</td>\n<td>Explicitly includes</td>\n</tr>\n<tr>\n<td>EXCLUDED</td>\n<td>Explicitly excludes</td>\n</tr>\n<tr>\n<td>SILENT</td>\n<td>Not addressed — <strong>most dangerous</strong></td>\n</tr>\n<tr>\n<td>PARTIAL</td>\n<td>Includes with limitations</td>\n</tr>\n<tr>\n<td>DIFFERENT</td>\n<td>Offers substitution</td>\n</tr>\n</tbody>\n</table>\n<p>Flag all SILENT items on spec-required scope. Drawing-derived SILENT\nitems suggest incomplete document review by that bidder.</p>\n<h3>2c. Exclusion Risk Scoring</h3>\n<table>\n<thead>\n<tr>\n<th>Level</th>\n<th>Criteria</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>CRITICAL</td>\n<td>Spec-required, uncarried, &gt;1% bid or &gt;$5K</td>\n</tr>\n<tr>\n<td>SIGNIFICANT</td>\n<td>Implied by spec/practice, $2K-$5K</td>\n</tr>\n<tr>\n<td>MINOR</td>\n<td>Common GC-provided, &lt;$2K</td>\n</tr>\n<tr>\n<td>INFO</td>\n<td>Clarification only, no cost impact</td>\n</tr>\n</tbody>\n</table>\n<h3>2d. Qualification &amp; Responsibility</h3>\n<p>Assess per bidder: bonding, insurance, licensing, experience,\ncapacity, DBE/MBE, bid completeness.\n<strong>Bust detection:</strong> &gt;20-30% below field + scope gaps + incomplete\nsubmission. Flag for verification, never call it a bust.</p>\n<h3>2e. Responsiveness and the Recommendation</h3>\n<ul>\n<li>A <strong>curable</strong> defect (addenda not acknowledged; an illegible or missing\nline that reconciles to the stated total; validity shorter than required;\nbond not mentioned where one is required) keeps the bid in the ranking at\nits stated price.</li>\n<li>Recommend the apparent low bidder <strong>conditionally</strong>: each cure is a named\naward condition in <code>recommendation.conditions</code> (written addenda\nacknowledgment with no price change; a clean copy of the illegible line;\na validity extension; a bond commitment). Name the next fully responsive\nbidder as the fallback and state the spread.</li>\n<li>A figure derived for an illegible line is allowed only when it reconciles\nexactly to the stated total, and it is always labelled \"derived, confirm\",\nnever presented as read.</li>\n<li>A <strong>non-curable</strong> defect (budgetary-only pricing; a stale drawing basis the\nbidder has not re-confirmed; SILENT spec-required scope the bidder will not\ncarry) makes the bid \"not awardable as submitted\"; it is ranked but never\nrecommended.</li>\n</ul>\n<hr>\n<h2>Step 3: Output</h2>\n<p>Build JSON per schema in <code>scripts/sample_input.json</code> with the Write tool\n(not a shell heredoc, which fails here on an apostrophe, and not a helper\nscript) as <code>.construction/skills/bid-evaluator/bid_evaluation.json</code>: it is\nworking data, never in the project root. Then run:</p>\n<pre><code>\"${CLAUDE_PLUGIN_ROOT}/bin/construction-python\" \"${CLAUDE_SKILL_DIR}/scripts/export_bid_evaluation.py\" .construction/skills/bid-evaluator/bid_evaluation.json \"Bid_Evaluation_{package}.xlsx\"\n</code></pre>\n<p>Run it from the project folder: the workbook is the deliverable and goes in the project root (or the folder the PE names), never under <code>.construction/</code>, which macOS and Linux hide.</p>\n<p>The script produces 5 sheets: Bid Comparison, Price Summary,\nExclusion Detail, Qualification Summary, Recommendation.</p>\n<hr>\n<h2>Step 4: Handoff</h2>\n<ol>\n<li>Lead with the recommendation — don't make them hunt for it</li>\n<li>Highlight items needing PE attention</li>\n<li>Ask for explicit confirmation: selected bidder, scope adjustments,\nalternates, special conditions</li>\n</ol>\n<p><strong>Do NOT proceed to a subcontract without user confirmation.</strong> <code>subcontract-writer</code> is user-invoked only; once the user has confirmed the selected bidder, tell them the next step is <code>/construction:subcontract-writer</code> and stop.</p>\n<hr>\n<h2>Step 5: Write a Finding</h2>\n<p>Record the evaluation as a finding in <code>.construction/skills/bid-evaluator/findings/</code> (both modes):</p>\n<pre><code>\"${CLAUDE_PLUGIN_ROOT}/bin/construction-python\" \"${CLAUDE_PLUGIN_ROOT}/scripts/graph/write_finding.py\" \\\n  --skill \"bid-evaluator\" --type \"bid_evaluation_complete\" \\\n  --title \"Bid evaluation: {scope} — {N} bidders, recommended {company}\" \\\n  --output-file \"Bid_Evaluation_{package}.xlsx\" \\\n  --data '{\"scope\": \"...\", \"bidder_count\": N, \"recommended\": \"...\", \"adjusted_amount\": ..., \"pe_attention_items\": [...]}'\n</code></pre>\n<hr>\n<h2>Context Needs Chart</h2>\n<table>\n<thead>\n<tr>\n<th>Step</th>\n<th>Resource</th>\n<th>Load Trigger</th>\n<th>Offload After</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1b</td>\n<td><code>references/drawing-review.md</code></td>\n<td>Drawing sheets provided</td>\n<td>Step 1b complete</td>\n</tr>\n<tr>\n<td>2</td>\n<td><code>references/buyout-domain.md</code></td>\n<td>Entering bid analysis</td>\n<td>Step 2d complete</td>\n</tr>\n<tr>\n<td>3</td>\n<td><code>scripts/sample_input.json</code></td>\n<td>Building output JSON</td>\n<td>Step 3 complete</td>\n</tr>\n<tr>\n<td>5</td>\n<td><code>${CLAUDE_PLUGIN_ROOT}/scripts/graph/write_finding.py</code></td>\n<td>Step 5</td>\n<td>Step 5 complete</td>\n</tr>\n</tbody>\n</table>\n<h2>Gotchas (measured in eval runs)</h2>\n<ul>\n<li>Write JSON and YAML with the Write tool. <code>cat &gt; file &lt;&lt;'EOF'</code> failed with \"unexpected EOF while looking for matching <code>'</code>\" whenever the content held an apostrophe (3 of 15 runs, 2026-10-04), costing a turn each time.</li>\n<li>Do not write helper scripts or inline <code>python -c</code>, even to assemble your own JSON or to read a PDF; the allowlisted scripts are the toolkit, and the exporters do the arithmetic checks. If the toolkit lacks something you need, say so in the handoff instead (bid-tabulator and subcontract-writer each wrote a helper script in their 2026-10-04 runs; the eval guard blocked both).</li>\n</ul>\n<h2>Error Handling</h2>\n<ul>\n<li>Uneven formats: note difficulty, don't penalize lump-sum bids</li>\n<li>&lt;3 bids: note limited field, suggest re-bid if appropriate</li>\n<li>Budget mixed with hard bids: segregate with caveat</li>\n<li>Math errors: flag discrepancy, don't correct</li>\n<li>Scope too complex: focus on highest cost-impact items</li>\n</ul>\n<h2>What This Skill Does NOT Do</h2>\n<ul>\n<li>Contact subs, execute awards, or negotiate pricing</li>\n<li>Replace PE judgment on responsibility</li>\n<li>Produce subcontracts (use /subcontract-writer)</li>\n<li>Perform quantity takeoffs from drawings</li>\n</ul>\n<h2>File Safety</h2>\n<p>Never overwrite an existing bid evaluation. The export script uses <code>safe_output_path()</code> which appends <code>_v2</code>, <code>_v3</code>, etc. automatically.</p>\n<hr>\n<h2>Allowed Scripts</h2>\n<ul>\n<li><code>${CLAUDE_PLUGIN_ROOT}/bin/construction-python</code></li>\n<li><code>${CLAUDE_PLUGIN_ROOT}/scripts/pdf/pdf_text.py</code> — spec section and bid text (Step 1a)</li>\n<li><code>${CLAUDE_PLUGIN_ROOT}/scripts/pdf/rasterize_page.py</code> — drawing sheets and VISION pages</li>\n<li><code>${CLAUDE_SKILL_DIR}/scripts/export_bid_evaluation.py</code></li>\n<li><code>${CLAUDE_PLUGIN_ROOT}/scripts/graph/write_finding.py</code></li>\n<li><code>${CLAUDE_PLUGIN_ROOT}/scripts/corrections_append.py</code> — AgentCM mode: record a correction of AgentCM's data (<code>reference/agentcm-mode.md</code>)</li>\n</ul>\n<p>No other code: no <code>python -c</code>, no helper script. If the toolkit lacks something\nyou need, say so in the handoff.</p>\n","files":[{"path":"agents/openai.yaml","sizeBytes":286,"isText":true},{"path":"references/buyout-domain.md","sizeBytes":5378,"isText":true},{"path":"references/drawing-review.md","sizeBytes":3649,"isText":true},{"path":"scripts/export_bid_evaluation.py","sizeBytes":17860,"isText":true},{"path":"scripts/sample_input.json","sizeBytes":4609,"isText":true},{"path":"scripts/shared.py","sizeBytes":554,"isText":true},{"path":"SKILL.md","sizeBytes":12166,"isText":true}],"reviewScore":null,"reviewSummary":null,"trust":{"provenance":"trusted-source-unreviewed","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow.","bodySource":null},"bodyLocked":false,"purchaseUrl":null,"sourceUrl":null,"report":{"provenance":"trusted-source-unreviewed","screen":{"ran":true,"outcome":"clean","suspicious":0,"notes":0,"hiddenCharacters":false},"virusScan":{"engine":"clamav","status":"clean","scannedAt":"2026-10-19T21:17:10.603888Z","sha256":"4E6EC4630AA3497AC95C184B29417A247FC859B08F896B86CD876293565C2B64","sizeBytes":16814},"review":null,"source":{"repositoryUrl":"https://github.com/dleerdefi/claude-code-construction","path":"skills/bid-evaluator","license":"MIT","commit":"5c46e16c67cdc82ee8bcbb0fdd8ba316d792d4ec","subtreeSha":"E573EA74B84CF5942671B754F392CC08AECECFB8E987F55EDD112BF3A00A0F24","lastSyncedAt":"2026-10-19T21:17:01.926806Z"},"reviewedAt":"2026-10-19T21:17:20.145882Z","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow."},"install":[{"target":"skills-cli","command":"npx skills add https://github.com/dleerdefi/claude-code-construction/tree/main/skills/bid-evaluator"},{"target":"claude-code","command":"claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install dleerdefi-claude-code-construction@llmmart"},{"target":"git","command":"git clone https://github.com/dleerdefi/claude-code-construction.git"}]}