How CareerOps Handles Derived/Accumulated Sources and Quantified Claims
CareerOps enforces a two-tier trust model that isolates primary user-authored content from accumulated narrative sources, using a four-bucket classification system in story-provenance-check.mjs to ensure unverified quantified claims never propagate as factual data.
CareerOps (santifer/career-ops) implements a rigorous data governance framework to manage quantified claims originating from derived or accumulated sources. The system distinguishes between authoritative user-authored documents and narrative story banks, ensuring that only verified numeric statements with explicit provenance reach downstream generators like CV renderers and cover letter builders.
Source-of-Truth Architecture
CareerOps maintains strict source-of-truth boundaries defined in [AGENTS.md], segregating content into two distinct trust tiers.
Primary Tier: Full-Trust Ground Truth
Files in the primary tier are treated as authoritative for all factual content:
cv.md– The canonical curriculum vitae containing verified employment metricsconfig/profile.yml– Structured configuration datamodes/_profile.md– Profile metadata and constraints
These files represent user-authored ground truth where numeric statements carry implicit verification.
Derived Tier: Accumulated Narratives
The interview-prep/story-bank.md file operates as an accumulated source. It captures STAR-format (Situation, Task, Action, Result) interview stories that frequently contain quantitative claims (percentages, team sizes, performance metrics) but are not considered authoritative without additional provenance markers. This separation prevents narrative embellishment from contaminating factual records.
Four-Bucket Classification System
The [story-provenance-check.mjs] script implements a classifier that scans story-bank.md for numeric patterns—including percentages, "+ noun" constructs, hour ranges, hyphen scales, and noun scales—and assigns each claim to one of four buckets:
existing – The exact number or range appears verbatim in cv.md, or the story entry carries a **Provenance:** user‑stated YYYY‑MM‑DD marker confirming user verification.
supportedByResume – The number does not appear verbatim in cv.md, but the CV text describes the same fact with sufficient word overlap to deem it plausibly true based on heuristic matching.
derived‑unverified – The number appears only in the story-bank entry, lacks traceable CV support, and contains no provenance marker. This is the default safe state for unverified accumulated claims.
user‑cannot‑confirm – The story entry’s provenance is explicitly set to user‑cannot‑confirm, a durable override that prevents re-classification and marks the claim as unknowable.
The Provenance Field Convention
Each story block may include a dedicated **Provenance:** label distinct from the standard Source label. The field accepts one of four values:
source: cv.md– Creates a hard link back to the canonical CV fileuser‑stated YYYY‑MM‑DD– Records manual confirmation with an ISO datestampderived‑unverified– Explicitly marks the claim as unverified (redundant with absence, but explicit)user‑cannot‑confirm– Permanently excludes the claim from verification workflows
The absence of any provenance field is interpreted as derived‑unverified by default. This convention is implemented in the parsing logic of [story-provenance-check.mjs].
UX Invariant for Confirmation
When a derived‑unverified finding surfaces in the UI, CareerOps enforces a strict confirmation UX invariant that presents four unbiased options to prevent accidental verification:
- Confirm the claim as stated (writes
user‑stateddate) - Provide the correct figure (updates value and provenance)
- Mark the claim as narrative‑only (removes quantified status)
- Choose "I don’t know" (writes
user‑cannot‑confirm)
This invariant ensures that user guesses never become implicit verified facts. The requirement is documented in the "Confirmation UX invariant" section of [AGENTS.md] and enforced as read-only logic in [story-provenance-check.mjs].
Pipeline Enforcement and Downstream Usage
Downstream generators—including CV renderers, cover letter builders, and interview prep modules—consult the provenance classification before including quantified data:
- Allowed for factual rendering: Claims classified as
existingorsupportedByResumemay appear in factual tables, negotiation talking points, and quantitative achievement lists. - Narrative texture only: Claims marked
derived‑unverifiedoruser‑cannot‑confirmare treated as qualitative narrative texture and are explicitly omitted from any factual tables, metric summaries, or compensation negotiation data.
This enforcement ensures that only cv.md-verifiable or user-confirmed numbers appear in professional documents generated by the system.
Running the Provenance Checker
Execute the provenance validation pipeline using Node.js:
# Default usage – scans the default story-bank and CV
node story-provenance-check.mjs
# Summarize results for CI integration
node story-provenance-check.mjs --summary
# Analyze custom file paths
node story-provenance-check.mjs \
--story-bank interview-prep/my-company-role.md \
--cv cv.md
Adding Provenance Markers Manually
Edit interview-prep/story-bank.md to include a provenance label:
### Leadership
**Situation:** Led a team of 8 engineers.
**Task:** Deliver a new microservice.
**Action:** Designed the architecture.
**Result:** Deployed in 2 weeks, **30%** faster than previous releases.
**Provenance:** user-stated 2026-08-10 <!-- confirms the 30% figure -->
Programmatic Classification Logic
The core classification heuristic from [story-provenance-check.mjs] operates as follows:
function classifyStoryBank(storyText, cvText) {
const claims = extractClaims(storyText); // uses CLAIM_PATTERNS
return claims.map(claim => {
if (cvText.includes(claim.text)) return 'existing';
if (hasProvenance(claim, 'user-cannot-confirm')) return 'user-cannot-confirm';
if (hasProvenance(claim, 'derived-unverified')) return 'derived-unverified';
return 'supportedByResume';
});
}
Summary
- CareerOps separates data into primary (
cv.md,config/profile.yml) and derived (interview-prep/story-bank.md) trust tiers to prevent narrative drift. - The
[story-provenance-check.mjs]script classifies quantified claims into four buckets:existing,supportedByResume,derived‑unverified, anduser‑cannot‑confirm. - The
**Provenance:**field convention links claims tocv.mdsources, user confirmation dates, or explicit unknowable states. - Downstream generators only render claims marked
existingorsupportedByResumeas factual data;derived‑unverifiedclaims remain narrative-only. - The confirmation UX invariant requires explicit user action to upgrade any
derived‑unverifiedclaim, preventing accidental data pollution.
Frequently Asked Questions
How does CareerOps distinguish between primary and derived sources?
Primary sources include cv.md, config/profile.yml, and modes/_profile.md, which serve as the authoritative ground truth for all factual content. Derived sources like interview-prep/story-bank.md are accumulated narrative documents that may contain quantified claims but require verification against primary sources or explicit provenance markers before being treated as factual.
What happens to quantified claims that cannot be verified?
Claims classified as derived‑unverified or user‑cannot‑confirm are restricted to narrative usage only. Downstream generators will omit these numbers from factual tables, metric summaries, and negotiation talking points, ensuring that unsubstantiated figures never appear in professional documents exported from the system.
How do I manually confirm a quantified claim in story-bank.md?
Add a **Provenance:** line to the story entry with the value user‑stated YYYY‑MM‑DD using an ISO date format. Alternatively, ensure the exact number appears in cv.md, which the [story-provenance-check.mjs] script will detect and classify as existing automatically during the next validation run.
Can derived-unverified claims ever appear in exported CVs?
No. The pipeline enforcement rules explicitly prohibit derived‑unverified and user‑cannot‑confirm claims from appearing in any generated CV, cover letter, or factual summary. Only claims reaching existing or supportedByResume status through CV-verification or manual confirmation propagate to exported documents.
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 →