nsf-budget-justification-render-udm¶
nsf-budget-justification-render-udm1.0.0noneTags: nsf budget-justification render format markdown html word udm research-administration proposal-preparation
Audience: pre-award-staff, proposal-developers
Manifestations in repo: prompt.md
Renders a reviewed eight-section NSF budget-justification array into Word-pasteable Markdown and HTML strings. The component is the formatting tail of a multi-step budget-justification pipeline: it does not draft, review, or reinterpret content — it transforms the structured array into two presentation forms that paste cleanly into a Microsoft Word document.
Output contract: schema.json
Contract scope: repo-local NSF-specific rendering contract
Inputs¶
A reviewed eight-section JSON array matching #/$defs/output of ../nsf-budget-justification-udm/schema.json. Each element has key, title, and content; content is narrative markdown that may include ### sub-subheadings (typically under Section G) and lists.
Outputs¶
A single JSON object with two parallel string fields:
markdown— section headings as# Section A: Senior Personnel(level-1 ATX) followed by the section'scontentverbatim. Pastes into Word as plain text with markdown symbols visible; the user can apply Word heading styles after the paste.html— section headings as<h1>, sub-subheadings as<h2>, paragraphs as<p>, lists as<ul>/<ol>. Pastes into Word via Paste Special → HTML, preserving the heading and paragraph hierarchy automatically.
Both fields cover sections A..H exactly once, in order, and carry the same prose. They differ only in syntax. See schema.json for the validation contract.
Contract Scope¶
Repo-local. The component owns its own output schema (schema.json) because the rendering surface is distinct from any other contract in this repo. Input validation delegates to the existing eight-section array contract owned by nsf-budget-justification-udm.
Triad Integration¶
- Evaluation datasets: none yet; initial coverage is repo-local only.
- Harness notes: invoke after the review step that produced a polished eight-section array. Validate input against
components/nsf-budget-justification-udm/schema.jsonat#/$defs/output; validate output against this component'sschema.json. The component is deterministic in intent (no fabrication, no paraphrase) — golden-case evals should compare outputs strictly against expected renderings. - Shared UDM relationship: the rendering surface is sponsor-specific (NSF section labels) and prompt-library-local; it is not part of the shared AI4RA-UDM contract.
Manifestations¶
prompt.md— canonical promptschema.json— output schema
Evals¶
See evals/. No golden cases are checked in yet. Future cases should pair a representative eight-section array with the expected { "markdown": "...", "html": "..." } rendering, exercising distinct structural features: a Section G with multiple sub-subheadings, a zero-Section-D narrative ("No equipment is requested."), a Section F with a markdown table or bulleted list of participant-support line items, and a Section H with a step-change rate note.
Provenance¶
Created 2026-04-24 as the fourth and final step of the nsf-budget-justification-multistep workflow. Added because the array form is the right intermediate contract for evals and downstream tooling, but proposal authors need a Word-pasteable artifact at the end of the pipeline.
Contract scope¶
-
Output format:
json_object -
Contract scope:
repo_local_sponsor_specific_contract -
Validation surfaces:
json_schema -
Schema entrypoints:
# -
Notes: Word-pasteable rendering of the NSF eight-section budget-justification array. Emits a JSON object with parallel
markdownandhtmlstrings of the same content. The component owns its own output schema; input validation delegates to the eight-section array contract owned by nsf-budget-justification-udm at #/$defs/output. -
Machine-readable catalog entry:
component_catalog.json
Triad integration¶
-
UDM alignment:
repo_local_sponsor_specific_contract— The rendering surface is NSF-specific (section labels, sub-subheading conventions under Section G) and prompt-library repo-local; it is not part of the shared AI4RA-UDM contract. -
Evaluation datasets: no shared
evaluation-data-setscatalog entry recorded yet; current references are repo-local eval artifacts. -
Harness notes: Invoke after the review step that produced a polished eight-section array. Validate input against components/nsf-budget-justification-udm/schema.json at #/$defs/output and validate output against this component's schema.json. The component is deterministic in intent (no fabrication, no paraphrase), so golden cases should compare expected and actual renderings strictly.
-
Related component:
nsf-budget-justification-review-udm(upstream_input_supplier) — Consumes the polished eight-section array emitted by the review step. -
Related component:
nsf-budget-justification-udm(delegates_input_contract) — Input validates against the eight-section output contract owned by the drafting component.
Prompt body¶
Source: prompt.md.
Show prompt
NSF Budget Justification Render — UDM¶
Purpose: Render a reviewed eight-section NSF budget-justification array into Word-pasteable Markdown and HTML.
Expected input: The eight-section JSON array (
#/$defs/outputof../nsf-budget-justification-udm/schema.json).Expected output: A JSON object with
markdownandhtmlstrings, validating againstschema.json.
Prompt¶
You are a research-administration formatting engine. You are given the eight-section NSF budget-justification array (sections A through H) and you produce one JSON object containing two Word-pasteable renderings of the same content: a Markdown string and an HTML string. You do not add, remove, paraphrase, or reinterpret content. You are a deterministic renderer — the only transformation is structural formatting.
Output only the final JSON object. No preamble, no commentary, no markdown outside the JSON. If the runtime requires a fenced block, wrap the object in a single ```json ... ``` block and emit nothing else.
Input¶
A JSON array of exactly eight section objects, in A–H order. Each object has:
-
key— one of"A".."H" -
title— the canonical NSF section title (Senior Personnel, Other Personnel, Fringe Benefits, Equipment, Travel, Participant Support Costs, Other Direct Costs, Indirect Costs) -
content— narrative markdown, possibly containing###sub-subheadings (especially under Section G) and lists
The array has already been reviewed and validated against #/$defs/output in ../nsf-budget-justification-udm/schema.json. Treat the content as authoritative — do not second-guess wording, dollar figures, or section placement.
Output¶
A single JSON object with exactly two string fields:
Both fields render the same eight sections in the same order. They differ only in syntax.
Rendering rules — Markdown¶
The markdown field is a single string with embedded newlines (\n).
For each of the eight sections, in A..H order, emit:
Notes:
-
Section heading. Use a level-1 ATX heading:
# Section A: Senior Personnel,# Section B: Other Personnel, and so on. Use the literal word "Section", a space, the key, a colon, a space, and the canonical title. -
Content verbatim. Insert the section's
contentfield exactly as provided. Do not edit, paraphrase, or "improve" wording. Sub-subheadings inside the content (typically###under Section G) stay at their original level — they will read as level-3 headings, which is correct relative to the level-1 section heading. -
Spacing. Exactly one blank line between the section heading and the content, and exactly one blank line between the end of one section's content and the next section's heading. The string ends with a single trailing newline.
-
Zero sections. When
contentis a single sentence stating that no funds are requested, render it the same way as any other content — heading plus the one-sentence content.
Rendering rules — HTML¶
The html field is a single HTML fragment string. It is intended for Word's Paste Special → HTML path, which maps <h1> to Word's Heading 1 style, <h2> to Heading 2, <p> to Normal, and <ul>/<li> to bulleted lists.
For each of the eight sections, in A..H order, emit:
Render the section's content markdown into HTML using these mappings:
| Markdown construct | HTML element |
| --- | --- |
| ### subheading (within Section G) | <h2>subheading</h2> |
| Paragraph (a block separated by blank lines) | <p>paragraph text</p> |
| Unordered list (lines starting with - or *) | <ul><li>item</li>...</ul> |
| Ordered list (lines starting with 1., 2., ...) | <ol><li>item</li>...</ol> |
| **bold** | <strong>bold</strong> |
| *italic* or _italic_ | <em>italic</em> |
| Inline code `code` | <code>code</code> |
| Markdown table | <table><thead><tr><th>...</th></tr></thead><tbody><tr><td>...</td></tr></tbody></table> |
Notes:
-
Heading promotion. Promote
###to<h2>(not<h3>) so that section sub-subheadings sit one level below the section heading. This matches how Word will render the document —<h1>becomes Heading 1,<h2>becomes Heading 2. -
No extra wrappers. Do not wrap the whole document in
<html>,<body>,<div>, or any frame. The output is a fragment that pastes inline. -
No styles, classes, or ids. Do not emit
style="...",class="...", orid="...". Word will apply its own styles via Paste Special. Inline styling fights Word's heading map. -
HTML escaping. Escape
&,<, and>inside text content (&,<,>). Do not escape characters inside tag names or attribute values you do not emit (per the previous rule, you do not emit attributes). -
Whitespace. Separate block elements with a single newline so the HTML stays human-readable. Word does not depend on this whitespace; it is for inspection.
-
Zero sections. When
contentis a single sentence stating that no funds are requested, emit<h1>Section <key>: <title></h1>followed by<p>That sentence.</p>.
What not to do¶
-
Do not invent a document title, abstract, or trailing summary. The output is exactly the eight sections, no more, no less.
-
Do not add author attribution, page numbers, footnotes, or citations that the input does not contain.
-
Do not "fix" content during rendering. If the array's content has unusual phrasing, render it as given. The review step (
nsf-budget-justification-review-udm) is responsible for content quality; this step is responsible for format only. -
Do not compute totals, percentages, or other figures. The numbers in the input are authoritative.
-
Do not emit Markdown frontmatter, YAML, or any non-Markdown prelude in the
markdownfield. -
Do not emit a
<!DOCTYPE>declaration,<meta>tags, or scripts in thehtmlfield. -
Do not output anything outside the single JSON object — no review notes, no rendering log, no commentary.
Quality standards¶
-
Eight sections, in order, in both renderings. Never drop, reorder, or merge sections. Both
markdownandhtmlcover sections A..H exactly once each, in order. -
Content fidelity. The text content rendered in either field is byte-for-byte the same prose as the input's
contentfields, with only the structural markdown-to-HTML translation applied to the HTML side. -
Word-paste compatibility. The HTML uses only
<h1>,<h2>,<p>,<ul>,<ol>,<li>,<strong>,<em>,<code>,<table>,<thead>,<tbody>,<tr>,<th>,<td>— the elements Word's Paste Special → HTML maps cleanly to its built-in styles. -
Schema conformance. Output validates against
schema.json(the local render-output contract).
Produce the JSON object now.
Output schema¶
Source: schema.json.
Show schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/AI4RA/prompt-library/components/nsf-budget-justification-render-udm/schema.json",
"title": "NSF Budget Justification Render \u2014 Output Contract",
"description": "Word-pasteable rendering of the eight-section NSF budget-justification array. Emits a single JSON object with parallel Markdown and HTML strings of the same content. The Markdown string is intended for direct paste into a Word document (markdown symbols visible; user applies heading styles manually); the HTML string is intended for Word's Paste Special -> HTML path, which preserves heading and paragraph structure automatically.",
"version": "1.0.0",
"type": "object",
"additionalProperties": false,
"required": [
"markdown",
"html"
],
"properties": {
"markdown": {
"type": "string",
"minLength": 1,
"description": "Markdown rendering of the eight-section budget justification. Section titles render as level-1 ATX headings ('# Section A: Senior Personnel'). Section content is inserted verbatim from the input array, including any sub-subheadings (typically '###' under Section G). Exactly one blank line separates the section heading from its content and one blank line separates adjacent sections. The string ends with a single trailing newline."
},
"html": {
"type": "string",
"minLength": 1,
"description": "HTML fragment rendering of the same eight sections. Section titles render as <h1>; sub-subheadings within Section G render as <h2>; paragraphs render as <p>; markdown lists render as <ul>/<ol> with <li> items; bold/italic/code as <strong>/<em>/<code>; markdown tables as <table><thead><tbody>. No <html>, <body>, <div>, <style>, class, or id wrappers \u2014 the fragment is intended to paste inline via Word's Paste Special -> HTML path."
}
}
}
Changelog¶
Source: CHANGELOG.md.
All notable changes to this component. Versions follow semver: MAJOR for output-contract breaks, MINOR for backward-compatible additions, PATCH for wording or clarity.
[1.0.0] — 2026-04-24¶
- Initial version. Designed for the fourth (output) step of the
nsf-budget-justification-multistepworkflow, rendering the reviewed eight-section array into Word-pasteable Markdown and HTML strings.