# How Career-Ops Generates the Block E Customization Plan: From Template to Actionable Report

> Discover how Career-Ops creates the Block E Customization Plan by merging markdown templates with dynamic analysis. Generate actionable CV and LinkedIn recommendations.

- Repository: [Santiago Fernández de Valderrama/career-ops](https://github.com/santifer/career-ops)
- Tags: how-to-guide
- Published: 2026-08-22

---

**Career-Ops generates the Block E Customization Plan by combining a static markdown scaffold defined in [`modes/oferta.md`](https://github.com/santifer/career-ops/blob/main/modes/oferta.md) with dynamic gap analysis from Block D and archetype-specific guidance, then renders the results through the `auto-pipeline.mjs` script to produce a structured table of CV and LinkedIn recommendations.**

Career-Ops is an open-source evaluation framework that analyzes job descriptions against candidate profiles to generate detailed match reports. The **Customization Plan**—designated as Block E within the report structure—provides specific, actionable recommendations for tailoring a candidate's application materials to maximize role alignment.

## Template Architecture in modes/oferta.md

The foundation of Block E rests on a predefined markdown template that establishes the section's structure and formatting standards.

### The Block E Markdown Scaffold

The template file [`modes/oferta.md`](https://github.com/santifer/career-ops/blob/main/modes/oferta.md) defines the Block E section starting at line 200 with the heading `## Block E — Customization Plan`. This scaffold includes a markdown table with five distinct columns: **#**, **Section**, **Current status**, **Proposed change**, and **Why**. These columns create a standardized framework where the generation script later inserts concrete, role-specific recommendations.

### Top 5 Changes Structure

Within the template, the scaffold explicitly references the "Top 5 changes to CV + Top 5 changes to LinkedIn to maximize match." This structure directs the generation logic to prioritize the five highest-impact modifications for each platform, ensuring the resulting **Customization Plan** remains concise and actionable rather than overwhelming users with excessive recommendations.

## Data Sources and Input Gathering

The generation process relies on multiple data streams to populate the template with relevant, personalized content.

### Block D Analysis and Profile Data

When the evaluation pipeline executes via `node auto-pipeline.mjs` or `node oferta.mjs`, the engine first collects the **score and match analysis from Block D**, which contains research-driven gap identification. Concurrently, it retrieves user-specific **archetype information** stored in [`config/profile.yml`](https://github.com/santifer/career-ops/blob/main/config/profile.yml) and [`modes/_profile.md`](https://github.com/santifer/career-ops/blob/main/modes/_profile.md). These files provide the narrative guidance and targeting metadata necessary to tailor proposals to the candidate's professional persona.

### Source Content Files

The system references [`cv.md`](https://github.com/santifer/career-ops/blob/main/cv.md) and [`article-digest.md`](https://github.com/santifer/career-ops/blob/main/article-digest.md) to extract the **current wording and status** of existing candidate materials. These files serve as the baseline against which gaps are measured, providing the raw content that the **Customization Plan** will recommend modifying.

## Decision Logic and Rendering Pipeline

The actual population of Block E occurs through a systematic iteration process implemented in the report-generation scripts.

### The Gap Processing Loop

Located in `auto-pipeline.mjs` and `oferta.mjs`, the generation logic iterates over identified gaps from Block D. For each gap, the script executes four key operations:

1. **Section Identification**: Determines which applicant material requires updates (e.g., **Summary**, **CV**, or **LinkedIn** sections).
2. **Current State Capture**: Retrieves existing text from [`cv.md`](https://github.com/santifer/career-ops/blob/main/cv.md) or [`profile.yml`](https://github.com/santifer/career-ops/blob/main/profile.yml) via the `getCurrent(section)` function.
3. **Proposal Crafting**: Generates concrete suggested rewrites using `craftProposal(gap, archetype)`, incorporating archetype-specific narrative guidance.
4. **Rationale Generation**: Explains the strategic reasoning behind each suggestion through `explainWhy(gap, proposal)`.

The following pseudocode illustrates this core logic:

```javascript
// From the report generator in auto-pipeline.mjs / oferta.mjs
for (const gap of gaps) {
  const section = gap.section;               // e.g. “Summary”
  const current = getCurrent(section);       // read current text from cv.md / profile.yml
  const proposal = craftProposal(gap, archetype);
  const reason = explainWhy(gap, proposal);
  blockERows.push(`| ${idx} | ${section} | ${current} | ${proposal} | ${reason} |`);
}

report += `## Block E — Customization Plan\n\n| # | Section | Current status | Proposed change | Why |\n|---|---------|---------------|----------------|-----|\n${blockERows.join('\n')}\n`;

```

### Final Report Assembly

After processing all gaps, the script inserts the completed Block E table into the final report markdown file at `reports/<id>-<company>-<date>.md`. The output preserves the exact markdown format defined in [`modes/oferta.md`](https://github.com/santifer/career-ops/blob/main/modes/oferta.md), ensuring the **Customization Plan** renders correctly in standard markdown viewers while maintaining the structured table layout.

## Output Format and Actionable Insights

The completed **Customization Plan** delivers a concise, numbered list of specific sections requiring updates. Each row presents the present content, the recommended edit, and a brief explanation of how that change improves alignment with the target role. This structured approach transforms raw gap analysis into immediately actionable tasks, allowing candidates to systematically optimize their application materials based on data-driven insights from the Career-Ops evaluation engine.

## Summary

- **Template Definition**: The Block E structure originates in [`modes/oferta.md`](https://github.com/santifer/career-ops/blob/main/modes/oferta.md) (lines 200-207), which defines the markdown table scaffold with columns for numbering, section names, current status, proposed changes, and rationale.
- **Data Integration**: The generation process combines Block D gap analysis with archetype data from [`config/profile.yml`](https://github.com/santifer/career-ops/blob/main/config/profile.yml) and content from [`cv.md`](https://github.com/santifer/career-ops/blob/main/cv.md) and [`article-digest.md`](https://github.com/santifer/career-ops/blob/main/article-digest.md) to create personalized recommendations.
- **Rendering Logic**: The `auto-pipeline.mjs` and `oferta.mjs` scripts execute the evaluation flow, iterating through gaps to populate table rows with specific, actionable modifications.
- **Output Location**: The final **Customization Plan** renders as a structured markdown table in `reports/<id>-<company>-<date>.md`, providing candidates with prioritized CV and LinkedIn optimization strategies.

## Frequently Asked Questions

### What file defines the Block E Customization Plan structure?

The [`modes/oferta.md`](https://github.com/santifer/career-ops/blob/main/modes/oferta.md) file contains the template definition for Block E, specifically at lines 200-207 according to the Career-Ops source code. This markdown template establishes the table columns and static wording, including the "Top 5 changes to CV + Top 5 changes to LinkedIn" framework, which the generation scripts later populate with dynamic content.

### How does Career-Ops determine what changes to suggest?

The system analyzes gaps identified in **Block D** (research-driven match analysis) and cross-references these with the user's archetype data stored in [`config/profile.yml`](https://github.com/santifer/career-ops/blob/main/config/profile.yml) and [`modes/_profile.md`](https://github.com/santifer/career-ops/blob/main/modes/_profile.md). For each gap, the `craftProposal()` function generates specific text recommendations based on the archetype's narrative guidance, while `explainWhy()` provides strategic rationale for each suggested change.

### Which scripts actually generate the Block E table?

The **Customization Plan** table is generated by `auto-pipeline.mjs` and `oferta.mjs`, executed via `node auto-pipeline.mjs` or `node oferta.mjs` commands. These scripts orchestrate the evaluation flow, processing gap data and profile information to render the final markdown table with concrete recommendations.

### Where is the final Customization Plan report saved?

The completed report, including the populated Block E section, is saved to `reports/<id>-<company>-<date>.md`, where `<id>` represents the report identifier, `<company>` the target organization, and `<date>` the generation timestamp. This file contains the full evaluation with the structured **Customization Plan** ready for immediate candidate review and implementation.