Project Files
src / planning / dimensions.ts
/**
* @file planning/dimensions.ts
* The 12 research dimensions that constitute comprehensive coverage.
* Coverage detection requires minimum keyword density and context length.
*/
import { ResearchDimension } from "../types";
import {
DIMENSION_COVERAGE_MIN_HITS,
DIMENSION_COVERAGE_MIN_CHARS,
} from "../constants";
export const DIMENSIONS: ReadonlyArray<ResearchDimension> = [
{
id: "overview",
label: "Overview & Definition",
keywords: [
"what is",
"definition",
"refers to",
"is a type",
"means",
"overview",
"introduction",
],
queries: (t) => [
`what is ${t}`,
`${t} definition and overview`,
`${t} explained simply`,
`${t} introduction guide`,
],
},
{
id: "mechanism",
label: "How It Works",
keywords: [
"how",
"process",
"mechanism",
"steps",
"works by",
"procedure",
"method",
"approach",
],
queries: (t) => [
`how does ${t} work`,
`${t} mechanism process explained`,
`${t} technical architecture`,
`${t} step by step process`,
],
},
{
id: "history",
label: "History & Origins",
keywords: [
"history",
"origin",
"founded",
"invented",
"developed",
"background",
"timeline",
"evolution",
],
queries: (t) => [
`${t} history origin development`,
`${t} timeline evolution`,
`who invented ${t}`,
],
},
{
id: "current",
label: "Current State & Recent Developments",
keywords: [
"2024",
"2025",
"2026",
"recently",
"current",
"today",
"latest",
"new",
"update",
"now",
],
queries: (t) => [
`${t} latest news 2025`,
`${t} current state developments`,
`${t} recent updates 2026`,
`${t} latest breakthroughs`,
],
},
{
id: "applications",
label: "Applications & Use Cases",
keywords: [
"application",
"use case",
"used for",
"example",
"industry",
"practice",
"deploy",
"implement",
],
queries: (t) => [
`${t} real world applications examples`,
`${t} use cases industry`,
`${t} implementation case studies`,
`${t} practical deployment`,
],
},
{
id: "challenges",
label: "Challenges & Limitations",
keywords: [
"challenge",
"limitation",
"problem",
"issue",
"drawback",
"disadvantage",
"concern",
"risk",
"obstacle",
],
queries: (t) => [
`${t} challenges limitations problems`,
`${t} risks concerns drawbacks`,
`${t} common issues failures`,
`${t} barriers to adoption`,
],
},
{
id: "comparison",
label: "Comparisons & Alternatives",
keywords: [
"vs",
"versus",
"compared to",
"alternative",
"difference",
"better than",
"similar to",
],
queries: (t) => [
`${t} vs alternatives comparison`,
`${t} compared to competitors`,
`best ${t} alternatives`,
`${t} benchmark comparison`,
],
},
{
id: "evidence",
label: "Research Evidence & Data",
keywords: [
"study",
"research",
"found that",
"evidence",
"data",
"analysis",
"survey",
"paper",
"peer-reviewed",
],
queries: (t) => [
`${t} research study evidence peer-reviewed`,
`${t} scientific data analysis`,
`${t} statistics survey data`,
`${t} quantitative evidence`,
],
},
{
id: "expert",
label: "Expert Opinion & Analysis",
keywords: [
"expert",
"according to",
"opinion",
"analyst",
"researcher",
"professor",
"scientist",
"specialist",
],
queries: (t) => [
`${t} expert opinion analysis`,
`${t} leading researchers views`,
`${t} industry expert perspectives`,
],
},
{
id: "future",
label: "Future Outlook & Trends",
keywords: [
"future",
"trend",
"predict",
"forecast",
"outlook",
"next",
"coming",
"prospect",
"potential",
],
queries: (t) => [
`${t} future trends predictions`,
`${t} forecast outlook 2026 2027`,
`${t} emerging trends next generation`,
],
},
{
id: "controversy",
label: "Controversy & Criticism",
keywords: [
"controversy",
"criticism",
"debate",
"oppose",
"critique",
"disagree",
"concern",
"ethical",
],
queries: (t) => [
`${t} criticism controversy ethical debate`,
`${t} opposition arguments against`,
`${t} ethical concerns criticism`,
],
},
{
id: "economics",
label: "Economics & Market Impact",
keywords: [
"cost",
"price",
"market",
"economic",
"billion",
"million",
"revenue",
"growth",
"industry size",
],
queries: (t) => [
`${t} economic impact market size cost`,
`${t} market growth revenue forecast`,
`${t} pricing economics ROI`,
],
},
];
/** Returns dimension IDs with meaningful coverage based on hit count and context length. */
export function detectCoveredDimensions(
texts: ReadonlyArray<string>,
): ReadonlyArray<string> {
const combined = texts.join(" ").toLowerCase();
return DIMENSIONS.filter((dim) => {
let totalHits = 0;
let totalChars = 0;
for (const kw of dim.keywords) {
let idx = 0;
while ((idx = combined.indexOf(kw, idx)) !== -1) {
totalHits++;
const ctxStart = Math.max(0, idx - 25);
const ctxEnd = Math.min(combined.length, idx + kw.length + 25);
totalChars += ctxEnd - ctxStart;
idx += kw.length;
}
}
return (
totalHits >= DIMENSION_COVERAGE_MIN_HITS &&
totalChars >= DIMENSION_COVERAGE_MIN_CHARS
);
}).map((dim) => dim.id);
}
/**
* Returns the dimensions NOT yet covered by the collected sources.
*/
export function detectGaps(
coveredIds: ReadonlyArray<string>,
): ReadonlyArray<ResearchDimension> {
const coveredSet = new Set(coveredIds);
return DIMENSIONS.filter((d) => !coveredSet.has(d.id));
}
/**
* Generates gap-filling queries for a given list of uncovered dimensions.
*/
export function gapFillQueries(
topic: string,
gaps: ReadonlyArray<ResearchDimension>,
maxQueries: number,
): ReadonlyArray<string> {
const queries: string[] = [];
for (const dim of gaps) {
for (const q of dim.queries(topic)) {
if (!queries.includes(q)) queries.push(q);
if (queries.length >= maxQueries) return queries;
}
}
return queries;
}