test / corpus / synthetic-corpus.js
test / corpus / synthetic-corpus.js
/**
* Synthetic corpus for RSS RAG local testing.
*
* Version-controlled, small corpus with manually defined relevance expectations.
* Includes: late-arriving news, historical queries, syndicated duplicates,
* distinct updates, title/body matches, multilingual examples, restrictive filters.
*
* Labels are manually defined; do not generate expected rankings from implementation.
*/
// Synthetic articles with metadata
const articles = [
// --- Basic articles ---
{
id: 'a1',
title: 'Breaking: Tech Conference Announces New AI Framework',
summary: 'The tech world was abuzz as a major conference revealed a new open-source AI framework.',
content: 'A major conference revealed a new open-source AI framework. Developers can now access the codebase.',
pubDate: '2024-06-15',
feed: 'tech-crunch',
tags: '["tech", "ai", "open-source"]',
collection: 'tech',
sourceType: 'rss',
starred: false,
},
{
id: 'a2',
title: 'AI Framework Release Details',
summary: 'Full details of the new AI framework release, including installation and getting started.',
content: 'Installation guidelines and getting started tutorials for the new AI framework.',
pubDate: '2024-06-15',
feed: 'tech-crunch',
tags: '["tech", "ai", "framework"]',
collection: 'tech',
sourceType: 'rss',
starred: false,
},
// --- Late-arriving news (same event, different angle) ---
{
id: 'a3',
title: 'Follow-up: AI Framework Community Responds',
summary: 'Community members react to the new framework, posting plugins and extensions.',
content: 'Community plugins and extensions for the new AI framework have already begun appearing online.',
pubDate: '2024-06-20', // 5 days later - LATE ARRIVING
feed: 'tech-crunch',
tags: '["tech", "ai", "community"]',
collection: 'tech',
sourceType: 'rss',
starred: false,
},
// --- Historical query test ---
{
id: 'a4',
title: 'Historical: First AI Framework Announcement (2022)',
summary: 'Looking back at the first AI framework announced in 2022 and its impact.',
content: 'A retrospective look at the 2022 AI framework announcement and its long-term impact.',
pubDate: '2022-03-10',
feed: 'tech-archive',
tags: '["history", "ai", "framework"]',
collection: 'historical',
sourceType: 'rss',
starred: false,
},
// --- Syndicated duplicates (same content, different feed) ---
{
id: 'a5',
title: 'New AI Framework Announced at Conference',
summary: 'The tech conference announced a new open-source AI framework.',
content: 'A major conference revealed a new open-source AI framework. Developers can now access the codebase.',
pubDate: '2024-06-15',
feed: 'tech-journal',
tags: '["tech", "ai", "framework"]',
collection: 'tech',
sourceType: 'rss',
starred: false,
},
{
id: 'a6',
title: 'AI Framework Announcement (mirror)',
summary: 'Mirror of the AI framework announcement from the conference.',
content: 'A major conference revealed a new open-source AI framework. Developers can now access the codebase.',
pubDate: '2024-06-15',
feed: 'tech-mirror',
tags: '["tech", "ai", "framework"]',
collection: 'tech',
sourceType: 'rss',
starred: false,
},
// --- Distinct updates (different event, same topic) ---
{
id: 'a7',
title: 'New AI Framework Version 2.0 Released',
summary: 'The framework team released version 2.0 with major new features.',
content: 'Version 2.0 includes new features for performance and scalability.',
pubDate: '2024-09-01',
feed: 'tech-updates',
tags: '["tech", "ai", "version-2"]',
collection: 'tech',
sourceType: 'rss',
starred: false,
},
// --- Title/body match test ---
{
id: 'a8',
title: 'AI Framework Tutorial',
summary: 'Learn how to use the AI framework with this complete tutorial.',
content: 'A complete tutorial for the AI framework, covering installation, configuration, and example use cases.',
pubDate: '2024-06-20',
feed: 'tech-tutorials',
tags: '["tech", "ai", "tutorial"]',
collection: 'tech',
sourceType: 'rss',
starred: false,
},
// --- Multilingual examples ---
{
id: 'a9',
title: 'Framework AI: Nouvelles annonces',
summary: 'Annonces importantes du framework AI',
content: 'Des nouvelles fonctionnalités ont été ajoutées au framework AI.',
pubDate: '2024-06-15',
feed: 'tech-fr',
tags: '["tech", "ai", "francais"]',
collection: 'multilingual',
sourceType: 'rss',
starred: false,
},
// --- Restrictive filter test ---
{
id: 'a10',
title: 'Exclusive: AI Framework Funding Round',
summary: 'The framework startup just closed a Series A funding round.',
content: 'The AI framework startup announced a Series A funding round of $10M.',
pubDate: '2024-06-15',
feed: 'tech-funding',
tags: '["tech", "ai", "funding"]',
collection: 'funding',
sourceType: 'rss',
starred: true,
},
// --- Entity/name query test ---
{
id: 'a11',
title: 'Dr. AI: Framework Creator Interview',
summary: 'Interview with the creator of the new AI framework.',
content: 'In-depth interview with Dr. Smith about the motivations and goals behind the AI framework.',
pubDate: '2024-06-18',
feed: 'tech-interviews',
tags: '["tech", "ai", "interview", "dr-ai"]',
collection: 'entities',
sourceType: 'rss',
starred: false,
},
];
// Manually defined relevance expectations
// These are the "ground truth" the tester should verify against, NOT generated by the implementation
// Relevance: query "AI framework"
const relevanceAIFramework = {
// Should match (high relevance):
high: ['a1', 'a2', 'a5', 'a6', 'a7', 'a8', 'a10', 'a11'],
// Should match but lower relevance (late arriving, different angle):
medium: ['a3'],
// Should NOT match (wrong topic):
low: ['a4', 'a9'], // a4 is historical 2022, a9 is French language
// Duplicate/syndicated (same content, should be deduped):
duplicate: ['a5', 'a6'], // Same content, different feed
// Filter tests
byTagTech: ['a1', 'a2', 'a3', 'a5', 'a6', 'a7', 'a8', 'a10', 'a11'].filter(id => {
// Articles with "tech" tag
const article = articles.find(a => a.id === id);
return article && article.tags && article.tags.includes('"tech"');
}),
byFeedTechCrunch: ['a1', 'a2', 'a3'].map(id => articles.find(a => a.id === id).feed),
byDateAfterJune18: articles.filter(a => new Date(a.pubDate) > new Date('2024-06-18')).map(a => a.id),
};
// Relevance: query "funding"
const relevanceFunding = {
high: ['a10'],
low: ['a1', 'a2', 'a3', 'a5', 'a6', 'a7', 'a8', 'a9', 'a11'].filter(id => id !== 'a10'),
};
// Relevance: query "historical"
const relevanceHistorical = {
high: ['a4'],
low: ['a1', 'a2', 'a3', 'a5', 'a6', 'a7', 'a8', 'a9', 'a10', 'a11'],
};
// Relevance: query "Dr. AI" (entity)
const relevanceEntity = {
high: ['a11'],
low: ['a1', 'a2', 'a3', 'a5', 'a6', 'a7', 'a8', 'a9', 'a10'],
};
// Query–article relevance matrix (for verification)
const queryRelevance = {
'AI framework': relevanceAIFramework,
'funding': relevanceFunding,
'historical': relevanceHistorical,
'Dr. AI': relevanceEntity,
};
// Article metadata index
const articleIndex = {};
articles.forEach(a => { articleIndex[a.id] = a; });
// Export for testing
module.exports = { articles, relevanceAIFramework, relevanceFunding, relevanceHistorical, relevanceEntity, queryRelevance, articleIndex };
// Summary for documentation
console.log(`Synthetic corpus loaded: ${articles.length} articles`);
console.log(`Relevance queries: ${Object.keys(queryRelevance).join(', ')}`);
console.log(`Article IDs: ${articles.map(a => a.id).join(', ')}`);
console.log(`
Label semantics (verify these against implementation results):
- high: expected high relevance match
- medium: expected medium relevance (late-arriving, different angle)
- low: expected low/no relevance (wrong topic, wrong date, wrong language)
- duplicate: expected syndicated content (should be deduped)
- byTagTech: articles with "tech" tag
- byFeedTechCrunch: articles from tech-crunch feed
- byDateAfterJune18: articles published after 2024-06-18
`);/**
* Synthetic corpus for RSS RAG local testing.
*
* Version-controlled, small corpus with manually defined relevance expectations.
* Includes: late-arriving news, historical queries, syndicated duplicates,
* distinct updates, title/body matches, multilingual examples, restrictive filters.
*
* Labels are manually defined; do not generate expected rankings from implementation.
*/
// Synthetic articles with metadata
const articles = [
// --- Basic articles ---
{
id: 'a1',
title: 'Breaking: Tech Conference Announces New AI Framework',
summary: 'The tech world was abuzz as a major conference revealed a new open-source AI framework.',
content: 'A major conference revealed a new open-source AI framework. Developers can now access the codebase.',
pubDate: '2024-06-15',
feed: 'tech-crunch',
tags: '["tech", "ai", "open-source"]',
collection: 'tech',
sourceType: 'rss',
starred: false,
},
{
id: 'a2',
title: 'AI Framework Release Details',
summary: 'Full details of the new AI framework release, including installation and getting started.',
content: 'Installation guidelines and getting started tutorials for the new AI framework.',
pubDate: '2024-06-15',
feed: 'tech-crunch',
tags: '["tech", "ai", "framework"]',
collection: 'tech',
sourceType: 'rss',
starred: false,
},
// --- Late-arriving news (same event, different angle) ---
{
id: 'a3',
title: 'Follow-up: AI Framework Community Responds',
summary: 'Community members react to the new framework, posting plugins and extensions.',
content: 'Community plugins and extensions for the new AI framework have already begun appearing online.',
pubDate: '2024-06-20', // 5 days later - LATE ARRIVING
feed: 'tech-crunch',
tags: '["tech", "ai", "community"]',
collection: 'tech',
sourceType: 'rss',
starred: false,
},
// --- Historical query test ---
{
id: 'a4',
title: 'Historical: First AI Framework Announcement (2022)',
summary: 'Looking back at the first AI framework announced in 2022 and its impact.',
content: 'A retrospective look at the 2022 AI framework announcement and its long-term impact.',
pubDate: '2022-03-10',
feed: 'tech-archive',
tags: '["history", "ai", "framework"]',
collection: 'historical',
sourceType: 'rss',
starred: false,
},
// --- Syndicated duplicates (same content, different feed) ---
{
id: 'a5',
title: 'New AI Framework Announced at Conference',
summary: 'The tech conference announced a new open-source AI framework.',
content: 'A major conference revealed a new open-source AI framework. Developers can now access the codebase.',
pubDate: '2024-06-15',
feed: 'tech-journal',
tags: '["tech", "ai", "framework"]',
collection: 'tech',
sourceType: 'rss',
starred: false,
},
{
id: 'a6',
title: 'AI Framework Announcement (mirror)',
summary: 'Mirror of the AI framework announcement from the conference.',
content: 'A major conference revealed a new open-source AI framework. Developers can now access the codebase.',
pubDate: '2024-06-15',
feed: 'tech-mirror',
tags: '["tech", "ai", "framework"]',
collection: 'tech',
sourceType: 'rss',
starred: false,
},
// --- Distinct updates (different event, same topic) ---
{
id: 'a7',
title: 'New AI Framework Version 2.0 Released',
summary: 'The framework team released version 2.0 with major new features.',
content: 'Version 2.0 includes new features for performance and scalability.',
pubDate: '2024-09-01',
feed: 'tech-updates',
tags: '["tech", "ai", "version-2"]',
collection: 'tech',
sourceType: 'rss',
starred: false,
},
// --- Title/body match test ---
{
id: 'a8',
title: 'AI Framework Tutorial',
summary: 'Learn how to use the AI framework with this complete tutorial.',
content: 'A complete tutorial for the AI framework, covering installation, configuration, and example use cases.',
pubDate: '2024-06-20',
feed: 'tech-tutorials',
tags: '["tech", "ai", "tutorial"]',
collection: 'tech',
sourceType: 'rss',
starred: false,
},
// --- Multilingual examples ---
{
id: 'a9',
title: 'Framework AI: Nouvelles annonces',
summary: 'Annonces importantes du framework AI',
content: 'Des nouvelles fonctionnalités ont été ajoutées au framework AI.',
pubDate: '2024-06-15',
feed: 'tech-fr',
tags: '["tech", "ai", "francais"]',
collection: 'multilingual',
sourceType: 'rss',
starred: false,
},
// --- Restrictive filter test ---
{
id: 'a10',
title: 'Exclusive: AI Framework Funding Round',
summary: 'The framework startup just closed a Series A funding round.',
content: 'The AI framework startup announced a Series A funding round of $10M.',
pubDate: '2024-06-15',
feed: 'tech-funding',
tags: '["tech", "ai", "funding"]',
collection: 'funding',
sourceType: 'rss',
starred: true,
},
// --- Entity/name query test ---
{
id: 'a11',
title: 'Dr. AI: Framework Creator Interview',
summary: 'Interview with the creator of the new AI framework.',
content: 'In-depth interview with Dr. Smith about the motivations and goals behind the AI framework.',
pubDate: '2024-06-18',
feed: 'tech-interviews',
tags: '["tech", "ai", "interview", "dr-ai"]',
collection: 'entities',
sourceType: 'rss',
starred: false,
},
];
// Manually defined relevance expectations
// These are the "ground truth" the tester should verify against, NOT generated by the implementation
// Relevance: query "AI framework"
const relevanceAIFramework = {
// Should match (high relevance):
high: ['a1', 'a2', 'a5', 'a6', 'a7', 'a8', 'a10', 'a11'],
// Should match but lower relevance (late arriving, different angle):
medium: ['a3'],
// Should NOT match (wrong topic):
low: ['a4', 'a9'], // a4 is historical 2022, a9 is French language
// Duplicate/syndicated (same content, should be deduped):
duplicate: ['a5', 'a6'], // Same content, different feed
// Filter tests
byTagTech: ['a1', 'a2', 'a3', 'a5', 'a6', 'a7', 'a8', 'a10', 'a11'].filter(id => {
// Articles with "tech" tag
const article = articles.find(a => a.id === id);
return article && article.tags && article.tags.includes('"tech"');
}),
byFeedTechCrunch: ['a1', 'a2', 'a3'].map(id => articles.find(a => a.id === id).feed),
byDateAfterJune18: articles.filter(a => new Date(a.pubDate) > new Date('2024-06-18')).map(a => a.id),
};
// Relevance: query "funding"
const relevanceFunding = {
high: ['a10'],
low: ['a1', 'a2', 'a3', 'a5', 'a6', 'a7', 'a8', 'a9', 'a11'].filter(id => id !== 'a10'),
};
// Relevance: query "historical"
const relevanceHistorical = {
high: ['a4'],
low: ['a1', 'a2', 'a3', 'a5', 'a6', 'a7', 'a8', 'a9', 'a10', 'a11'],
};
// Relevance: query "Dr. AI" (entity)
const relevanceEntity = {
high: ['a11'],
low: ['a1', 'a2', 'a3', 'a5', 'a6', 'a7', 'a8', 'a9', 'a10'],
};
// Query–article relevance matrix (for verification)
const queryRelevance = {
'AI framework': relevanceAIFramework,
'funding': relevanceFunding,
'historical': relevanceHistorical,
'Dr. AI': relevanceEntity,
};
// Article metadata index
const articleIndex = {};
articles.forEach(a => { articleIndex[a.id] = a; });
// Export for testing
module.exports = { articles, relevanceAIFramework, relevanceFunding, relevanceHistorical, relevanceEntity, queryRelevance, articleIndex };
// Summary for documentation
console.log(`Synthetic corpus loaded: ${articles.length} articles`);
console.log(`Relevance queries: ${Object.keys(queryRelevance).join(', ')}`);
console.log(`Article IDs: ${articles.map(a => a.id).join(', ')}`);
console.log(`
Label semantics (verify these against implementation results):
- high: expected high relevance match
- medium: expected medium relevance (late-arriving, different angle)
- low: expected low/no relevance (wrong topic, wrong date, wrong language)
- duplicate: expected syndicated content (should be deduped)
- byTagTech: articles with "tech" tag
- byFeedTechCrunch: articles from tech-crunch feed
- byDateAfterJune18: articles published after 2024-06-18
`);