Skip to content

feat(proposal-builder): answer RFPs compliance-first from a company library - #9

Merged
mikeastock merged 1 commit into
mainfrom
proposal-builder-v2
Oct 7, 2026
Merged

mikeastock merged 1 commit into
mainfrom
proposal-builder-v2

Conversation

@mikeastock-bot

@mikeastock-bot mikeastock-bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Rebuilds proposal-builder around answering an owner's RFP after a go decision, compliance first. It still renders with pdfcn and Forme.

  • In:
    • the RFP (or RFP Intake's extraction)
    • a reusable company-library/ (projects, people, safety, approach text), each file dated when last verified
    • prior proposals
    • the user's fee and team details
  • Out:
    • the proposal PDF in the RFP's tab order
    • compliance-check.md
    • proposal.json, with a source on every claim
  • Draft until the user approves; nothing is signed or submitted.

How it works

templates/proposal-core.mjs is dependency-free. The renderer and scripts/check.mjs share it.

  • Blocking (the check exits 1):
    • a requirement no section answers
    • a missing required form
    • counted pages over the limit, measured per section on the rendered PDF with pdftotext
    • an unpriced fee
  • Warnings:
    • a requirement answered only by unconfirmed claims from prior proposals
    • library or prior sources older than freshnessMonths (default 12)
    • values that differ between sources (EMR, project values), flagged when the proposal uses the older one
  • Fee: an absent fee is unpriced, never $0. Lump sums must be positive and reconcile; percentage lines (CM fee, bonds) stay out of the total.
node scripts/setup.mjs ./workspace && cd workspace
npm run render -- proposal.json proposal.pdf
node /path/to/skill/scripts/check.mjs proposal.json --pdf proposal.pdf --out compliance-check.md

Renderer: RFP tab labels, project and team cards with a field grid, grouped narrative lists, a fee band and table, a forms checklist, and a compliance matrix appendix. In DRAFT, every item shows its source, and unconfirmed prior claims print in rust with "confirm still true".

Sample

Cedar Hollow County's Riverside Branch Library, a CM at Risk RFP with a 20-page limit. Inputs: the RFP PDF, Larkspur Builders' library, two prior proposal PDFs, and the user's fee and team email. Planted problems:

  • Tab G (small and local business, 5 points) has no library content
  • Form 2 isn't included
  • the 2024 proposal carries a 2023 EMR and a GMP instead of the final cost
  • a "within 3% of GMP" claim is lifted from the 2024 proposal

The rendered PDF is 10 pages, 6 of them counted toward the limit. The check reports 2 blocking items and 2 warnings.

Fixes from the 1.0.0 review

  • P1: a $0 proposal is no longer possible.
  • Every sample item cites a real page or library file.
  • PDF metadata is ASCII, so the title no longer shows mojibake.
  • Non-two-decimal currencies are rejected instead of rounded.
  • Setup: portable path check, npm.cmd on Windows, and cleanup on failure.

Verification

  • evals/tasks/proposal-builder/proposal-core.test.mjs: 12 tests. CI now installs Poppler. The tests cover:
    • the bundled compliance check reproduced byte for byte from the bundled PDF
    • per-section page measurement
    • fixing the planted gaps clears every blocking item
    • fee rules, validation, and exit codes
  • 10 deliberate breaks to the core each failed between 1 and 4 tests.
  • Rendering:
    • A fresh setup.mjs workspace rendered the sample.
    • Every page was rasterized and inspected; I fixed a card left alone on its own page.
    • The pdfinfo title is clean.
  • The page preview is 225 KB, under the catalog's 256 KB inline limit, so the marketing site can show it.
  • Not yet tested: a fresh agent building from a library and RFP it hasn't seen.

Version 2.0.0, marketplace 0.9.0.

Note

Rebuild proposal-builder as a compliance-first RFP response skill (v2.0.0)

  • Replaces the free-form brief-to-proposal workflow with an RFP response workflow: every submittal requirement, scored criterion, form, and page limit is mapped in proposal.json before writing, and content is drawn from a dated company library and prior proposals with per-item source citations.
  • Adds a shared dependency-free core (proposal-core.mjs) that validates proposal data (metadata, sources, RFP requirements, fees, currencies) and a compliance checker CLI (check.mjs) that measures PDF pages via Poppler and blocks handoff on unanswered requirements, missing forms, over-limit pages, or an unpriced fee.
  • Rewrites the renderer (render.tsx) to render dynamic sections (cards, letters, fee tables, forms checklists, compliance matrix) instead of the fixed four-chapter layout; draft PDFs show per-item source lines and flag unconfirmed prior-proposal claims.
  • Adds company-library sample data (projects, people, safety, boilerplate), a full Riverside Branch Library sample package, a data-contract reference, and a Node test suite (proposal-core.test.mjs); the validation workflow now installs Poppler and runs the new test command.
  • Risk: the old flat proposal shape and validate.mjs are removed — document-contract.md is deleted and replaced by data-contract.md, so any consumer of the former proposal format must migrate; the skill catalog entry moves from estimating to preconstruction and bumps to 2.0.0.

Macroscope summarized cfb582d.

@macroscopeapp

macroscopeapp Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Macroscope skipped reviewing this pull request. Per-review cost limit exceeded (workspace setting).

This review would cost an estimated $5.65, which exceeds your per-review limit of $3.00.

The top 3 files driving up this estimate:

File Diff Size Estimate
skills/proposal-builder/templates/render.tsx 28.37KB $1.42
skills/proposal-builder/samples/proposal.json 18.68KB $0.93
skills/proposal-builder/templates/proposal-core.mjs 17.60KB $0.88

Tip

To get this pull request reviewed, you can:

  1. Comment @macroscope-app on this PR to request a manual review (monthly spend limits still apply).
  2. Exclude the file(s) above from review by adding a pattern to your .macroscope/ignore.md — note that creating this file replaces Macroscope's built-in default ignores rather than extending them.
  3. Raise your cost limit in your workspace billing settings.

Turn off this reminder going forward

…ibrary

Reframe proposal-builder around RFP responses after a go decision. A shared,
dependency-free core validates proposal.json (requirements, forms, page
limit, sources, facts, sections, fee) and a new check script writes the
compliance check: unanswered requirements, missing forms, pages over the
limit measured on the rendered PDF, and an unpriced fee block submission;
unconfirmed prior-proposal claims, stale sources, and older conflicting
values are flagged. The pdfcn renderer follows the RFP's tab order with
project and team cards, a fee table, forms, and a compliance matrix.
Fixes the 1.0.0 review findings ($0 proposals, metadata mojibake, currency
rounding, setup portability). New county library CMAR sample.
@mikeastock
mikeastock merged commit 32380f0 into main Oct 7, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants