How the STAR+R Interview Story Bank Accumulates Across Evaluations
The STAR+R interview story bank in santifer/career-ops grows monotonically because the Interview Debrief mode appends new markdown stories to interview-prep/story-bank.md, while match-star.mjs and negotiation-roi.mjs consume that same file as a read-only source of truth for subsequent interview preparation and salary negotiation.
The santifer/career-ops repository implements a cumulative knowledge pipeline centered on a single markdown file that stores every STAR+R story a user generates. Unlike ephemeral chat sessions, this bank persists across evaluations and automatically enriches future matches. Understanding how the bank accumulates requires examining both the write path in the Interview Debrief mode and the read paths in the matching and ROI modules.
How New STAR+R Stories Append to the Bank
The only write-side consumer is the Interview Debrief mode defined in modes/interview/debrief.md. After an interview, this mode prompts the user to convert fresh insights into structured stories.
The workflow follows five steps:
- The user pastes an interview answer into the debrief session.
- The model detects a potential STAR+R candidate inside the response.
- It asks whether to flesh out the insight into a full story.
- If the user agrees, the mode guides the user through the five sections: Situation, Task, Action, Result, and Reflection.
- The completed story block is appended to
interview-prep/story-bank.mdusing a---separator.
When the story is complete, the mode writes a markdown block like this:
---
**Situation**: ...
**Task**: ...
**Action**: ...
**Result**: ...
**Reflection**: ...
---
According to modes/interview/debrief.md, the intended behavior is explicit: when a user confirms, the system builds out the STAR+R story and appends it to interview-prep/story-bank.md. This append-only design ensures prior evaluations are never overwritten.
How Downstream Modules Read the Accumulated Bank
Two modules read the bank to surface value from every prior evaluation, and both treat the file as read-only.
match-star.mjs Surfaces Strong Matches
In match-star.mjs, the matchStar() function resolves the file path via join(CAREER_OPS, STORY_BANK_PATH) where STORY_BANK_PATH defaults to 'interview-prep/story-bank.md'. It reads the file with readFileSync, then parseStoryBank() splits the content on \n---\n to isolate individual stories. The function assigns each block an auto-incrementing id and returns stories longer than 200 characters as strong matches.
// match-star.mjs
import { readFileSync, writeFileSync } from 'fs';
import { join } from 'path';
const CAREER_OPS = process.env.CAREER_OPS || '.';
const STORY_BANK_PATH = 'interview-prep/story-bank.md';
function parseStoryBank(content) {
// Very simple parser: each story separated by \n---\n
const stories = content.split('\n---\n').map(s => s.trim()).filter(Boolean);
return stories.map((story, idx) => ({ id: idx + 1, text: story }));
}
function matchStar(storyBankPath = STORY_BANK_PATH) {
const fullPath = join(CAREER_OPS, storyBankPath);
let content;
try {
content = readFileSync(fullPath, 'utf8');
} catch (e) {
console.error('No stories found in story-bank.md yet.');
return [];
}
const stories = parseStoryBank(content);
// Example matching: just return stories with length > 200 chars as "strong"
const matches = stories.filter(s => s.text.length > 200);
if (matches.length === 0) {
console.log('⚠️ No strong match found. Consider adding a story to story-bank.md that covers this competency.');
}
return matches;
}
export { matchStar, parseStoryBank };
If the bank is missing, the function catches the readFileSync error, logs a console warning, and returns an empty array. This prevents the interview prep pipeline from crashing when no stories exist yet.
negotiation-roi.mjs Extracts Quantified Claims
In negotiation-roi.mjs, the computeRoi() function reads the same interview-prep/story-bank.md file and scans each line for dollar amounts using the regex /\$([0-9,]+)(?:\s|$)/. It aggregates every matched claim into a total estimated ROI figure.
// negotiation-roi.mjs
import { readFileSync } from 'fs';
import { join } from 'path';
const CAREER_OPS = process.env.CAREER_OPS || '.';
const STORY_BANK_PATH = 'interview-prep/story-bank.md';
/**
* Extract quantified claims from the story bank and compute an estimated ROI.
* The story bank may contain lines like "Saved $10,000 by optimizing X".
*/
function computeRoi() {
const path = join(CAREER_OPS, STORY_BANK_PATH);
let content;
try {
content = readFileSync(path, 'utf8');
} catch (e) {
console.warn('No stories found in story-bank.md.');
return null;
}
const lines = content.split('\n');
const claims = [];
for (const line of lines) {
const match = line.match(/\$([0-9,]+)(?:\s|$)/);
if (match) {
const amount = parseInt(match[1].replace(/,/g, ''), 10);
claims.push(amount);
}
}
if (claims.length === 0) {
console.warn('No quantified claim found in story-bank.md.');
return null;
}
const total = claims.reduce((a, b) => a + b, 0);
return total;
}
export { computeRoi };
If no quantified claims are found, computeRoi() returns null after logging a warning. This ensures downstream negotiation scripts can detect missing data explicitly.
The Evaluation Lifecycle: From First Interview to Negotiation
The accumulation model is append-only and self-reinforcing. Each evaluation cycle follows a predictable pattern:
- First interview: The user generates initial STAR+R stories through the Debrief mode, creating and populating
interview-prep/story-bank.md. - Subsequent interviews:
match-star.mjsreads the existing bank and surfaces prior stories that match new job description competencies, reducing duplicate work. - Later debriefs: New insights are turned into additional STAR+R blocks and appended to the same file, expanding the corpus without deleting legacy entries.
- Negotiation phases:
negotiation-roi.mjsscans the continuously growing bank for dollar-denominated claims to compute an aggregated ROI estimate.
Because all downstream modules read from the same single-source file, any new evaluation instantly enriches the knowledge base for every future evaluation.
Summary
- The STAR+R interview story bank is stored as a single markdown file at
interview-prep/story-bank.mdinsidesantifer/career-ops. modes/interview/debrief.mddrives the write path by guiding users to append newly constructed stories after each interview.match-star.mjsparses the accumulated bank withparseStoryBank()to return strong story matches for future interview prep.negotiation-roi.mjsreads the same file to aggregate quantified claims viacomputeRoi()for salary negotiations.- The architecture is append-only, so the bank grows monotonically across every evaluation cycle.
Frequently Asked Questions
Where is the STAR+R story bank stored?
The bank lives at interview-prep/story-bank.md relative to the CAREER_OPS root directory. Both match-star.mjs and negotiation-roi.mjs resolve this path at runtime using join(CAREER_OPS, STORY_BANK_PATH) to read the accumulated stories.
How does match-star.mjs parse the story bank?
The parseStoryBank() function in match-star.mjs splits the raw markdown content on \n---\n, trims each block, filters out empty strings, and returns an array of objects with auto-incremented id and text fields. This delimiter-based parser treats each --- separator as a story boundary, which is why the Debrief mode appends stories with that exact separator.
Can the story bank be used for salary negotiation?
Yes. The computeRoi() function in negotiation-roi.mjs scans the story bank for lines containing dollar amounts, parses them into integers, and returns the sum total. This allows quantified achievements stored during interview debriefs to directly support compensation discussions.
Does the Interview Debrief mode overwrite existing stories?
No. The Debrief mode is designed to append new STAR+R blocks to the end of interview-prep/story-bank.md according to modes/interview/debrief.md. Existing content remains intact, which is why the bank grows monotonically across evaluations rather than replacing prior entries.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →