Tools · CLIN 0002 Proposal & capture
Page Budget Planner
PlannedSplit a page limit across volumes and sections by evaluation weight.
This tool is planned. There is nothing to open yet. What follows is the plan, and it can change before the tool ships. The guide below covers the same job by hand in the meantime. Jump to the full specification.
What it will do
Enter a volume’s page limit and the evaluation factors, with the working weights you read from Section M. The tool sets aside the pages you reserve for an introduction and splits the rest in proportion, so every writer knows their limit on the first day.
You bring
- The page limit, and what counts toward it
- The evaluation factors and your working weight for each
- Pages reserved for an introduction or summary
You get
- A page allocation for each section that adds up to the limit
Built from
- The solicitation’s Sections L and M
- FAR Part 15, on evaluation factors and their relative importance
Only material the government has officially released to the public. Where the rules live shows how to find and cite each one.
Do it by hand today
- Answer every requirement · Budget the pagesTurn a solicitation into a numbered list of requirements, a compliance matrix, an outline and a page budget, so nothing is missed.
True of every tool
- Free and open source.
- No paid tier, no ads, and the code is public.
- Runs in your browser.
- What you type or open is not sent anywhere.
- No tracking.
- No accounts, cookies or analytics.
- Shows its sources.
- Each result names the rule it rests on, so you can check it.
- Says what it does not do.
- It is an aid for your own work, not professional advice.
What happens to what you type shows how to confirm this yourself, and Check a tool’s answer is the method for verifying a result.
Want it sooner?
Requests decide what is built first. Say what you would use it for, and what you do by hand today.
Issues are public. Leave out real contract data, real rates and anything controlled. How to write a useful request.
Specification · draft
How it is meant to work, in detail
The inputs, the logic, the checks the tool has to pass and the worked examples it is tested against. It is a draft, and the tool is built from it, so it can change until the tool ships.
4 min readLast revised November 2026Source of this specification
Overview & Role#
The Page Budget Planner (page-budget-planner) belongs to CLIN 0002 — Proposal & capture in src/data/catalog.ts. It divides a solicitation's hard page limit across proposal volumes and sections in proportion to Section M evaluation weights, after reserving fixed pages for introductions, summaries, or counted front matter.
As explained in Answer every requirement, a page limit is a strict requirement: pages beyond the limit are commonly removed unread. Setting each writer's page budget on day one prevents last-minute cutting of scored technical content.
| Attribute | Value |
|---|---|
| Tool Slug | page-budget-planner |
| Catalog CLIN | 0002 — Proposal & capture |
| Stack Template | calculator (deterministic allocation math in Moldloft) |
| Runtime | 100% static browser-side HTML/CSS/JS (zero backend, zero runtime AI) |
| License | MIT |
Governing Regulations & Sources#
- FAR Part 15 & FAR 15.204-1 (Sections L and M): Section L establishes volume structure, page limits, and formatting constraints (paper size, margins, font size, line spacing, and whether covers, tables of contents, acronym lists, resumes, or fold-outs count toward the limit). Section M states the evaluation factors and their relative importance (numerical weights or qualitative rankings such as "significantly more important than").
- FAR 52.215-1 (Instructions to Offerors—Competitive Acquisition): Governs compliance with proposal preparation instructions and page-limit enforcement.
- Solicitation-specific counting rules: Because solicitations differ on whether covers, TOCs, compliance matrices, and resumes count toward the cap, the planner models fixed reservations explicitly so the user can align inputs to Section L.
Inputs, Processing Logic & Outputs#
Inputs
| Field | Type | Constraints & Defaults |
|---|---|---|
totalPageLimit | Integer >= 1 | Total allowed pages for the volume (from Section L). |
fixedAllocations | Array of { label, pages, counted } | Fixed pages (e.g., Introduction/Executive Summary, or counted TOC/Compliance Matrix). Items with counted: false are tracked separately and excluded from the totalPageLimit pool. |
sections | Array of { name, weight, minPages? } | Scored sections/factors with relative weights (percentages or points, normalized automatically if they do not sum to 100) and optional minimum floor (>= 0). |
roundingStep | Enum (1, 0.5) | Defaults to 1 (whole-page budgets) or 0.5 (half-page increments). |
Deterministic Processing Logic
- Available pool calculation:
countedFixed = sum(fixed.pages where fixed.counted === true)availablePages = totalPageLimit - countedFixed- Fails closed with a clear validation error if
countedFixed > totalPageLimitor ifsum(section.minPages) > availablePages.
- Weight normalization:
totalWeight = sum(section.weight)(must be> 0).share_i = section_i.weight / totalWeight
- Proportional allocation & largest-remainder rounding:
- Computes exact target
exact_i = availablePages * share_i, clamped to at leastminPages_i. - Floors each section to
roundingStep(floor(exact_i / step) * step) and distributes remainingstepunits deterministically by largest fractional remainder (tie-breaking by highest weight, then section order) so the allocated pages sum exactly toavailablePagesandcountedFixed + sum(allocated) === totalPageLimit.
- Computes exact target
- Word-count guidance (informational): Estimates approximate word budget (
allocatedPages * wordsPerPage, defaulting to350–450words/page depending on user-selected density) as a writer aid.
Outputs
- Volume Page Budget Table: Columns
Part / Section,Working Weight (%),Exact Share,Allocated Pages,Counted?, andEstimated Words. - Excluded Front/Back Matter Summary: Lists items marked
counted: false(e.g., covers, resumes, acronym lists if excluded by Section L) so writers still track total deliverable length. - Local Exports: CSV and Markdown table exports for immediate inclusion in the proposal kickoff plan.
Clean-Room & 5-Condition QA Requirements#
- Browser-only execution: All allocation arithmetic and largest-remainder rounding run in client-side JavaScript.
- Strict Content Security Policy (
connect-src 'self'): Enforcesdefault-src 'self'; connect-src 'self'; form-action 'none'. Capture strategies and volume outlines stay strictly local. - Zero tracking or accounts: No sign-in, cookies, analytics, or external requests. Any optional
localStoragepersistence is disclosed with a Clear local data control. - Offline execution: Works completely offline after initial load with zero external dependencies.
- Worked examples, citations & scope limits: Verified against the exact worked example in Answer every requirement and boundary edge cases (zero weights, over-allocated fixed pages, fractional remainders), cites FAR Part 15 / 52.215-1, carries an MIT
LICENSE, and states that working weights represent the bidder's reading of Section M prose—not official government scoring formulas—unless Section M states explicit point values.
Worked Example & Verification#
Synthetic Input (from Answer every requirement):
totalPageLimit:30fixedAllocations:Introduction and summary=2pages (counted: true)sections:Factor 1, technical approach— weight50Factor 2, management approach— weight30Factor 3, staffing— weight20
roundingStep:1
Step-by-step calculation:
availablePages = 30 - 2 = 28pages.- Exact shares:
- Factor 1:
28 × 0.50 = 14.0→14pages (remainder0.0) - Factor 2:
28 × 0.30 = 8.4→8pages (remainder0.4) - Factor 3:
28 × 0.20 = 5.6→5pages +1largest remainder =6pages (remainder0.6)
- Factor 1:
Expected Output:
| Part | Working Weight | Pages |
|---|---|---|
| Introduction and summary | — | 2 |
| Factor 1, technical approach | 50% | 14 |
| Factor 2, management approach | 30% | 8 |
| Factor 3, staffing | 20% | 6 |
| Total | 100% | 30 |
Boundary cases verified by Shakedown:
countedFixed > totalPageLimitdisplays an inline error and refuses to emit negative section budgets.totalWeight === 0displays an inline validation error instead of dividing by zero.- Unnormalized weights (e.g.,
5, 3, 2) normalize identically to50%, 30%, 20%.