paqad-ai
Version:
Spec-driven development framework — AI agents that think before they type
3,087 lines • 105 kB
JavaScript
import { createRequire as __paqadCreateRequire } from 'module'; const require = __paqadCreateRequire(import.meta.url);
import {
ChunkIndexManager,
RagService
} from "./chunk-YAYHLNWR.js";
import {
detectDecisionForks,
matchRuleTriggers
} from "./chunk-7Q65STES.js";
import {
getPrimaryStack
} from "./chunk-HNYZUZ7D.js";
import {
readGitChangedFiles
} from "./chunk-EQYAXXZO.js";
import {
require_out
} from "./chunk-P4RPU2KB.js";
import {
stripTrailingChars
} from "./chunk-LYNDVGNE.js";
import {
resolveAnalyticsGate
} from "./chunk-NCYDV2N5.js";
import {
engineLog
} from "./chunk-D6VEUSB6.js";
import {
COMPLEXITY_LEVELS,
require_dist,
resolveFrameworkConfig,
selectLane
} from "./chunk-ACJQW7SB.js";
import {
slugifyAscii
} from "./chunk-AZLA53A6.js";
import {
PATHS
} from "./chunk-IHMBVS6H.js";
import {
__toESM,
init_esm_shims
} from "./chunk-IDFRWBMN.js";
// src/compliance/defect-patterns/types.ts
init_esm_shims();
var DEFECT_PATTERN_SCHEMA_VERSION = 1;
// src/compliance/defect-patterns/store.ts
init_esm_shims();
import { mkdir, readFile, readdir, writeFile } from "fs/promises";
import os from "os";
import path from "path";
var EXAMPLE_CAP = 5;
var STALENESS_DAYS = 365;
function defaultStoreRoot() {
return path.join(os.homedir(), ".paqad", "defect-patterns");
}
async function recordFindings(findings, storeRoot = defaultStoreRoot()) {
if (findings.length === 0) return;
await ensureStoreDir(storeRoot);
const index = await loadIndex(storeRoot);
for (const finding of findings) {
await upsertPattern(finding, index, storeRoot);
}
index.updated_at = (/* @__PURE__ */ new Date()).toISOString();
await saveIndex(index, storeRoot);
}
async function queryPatterns(options, storeRoot = defaultStoreRoot()) {
const index = await loadIndex(storeRoot);
const minFrequency = options.min_frequency ?? 3;
const maxAgeDays = options.max_age_days ?? STALENESS_DAYS;
const limit = options.limit ?? 5;
const cutoff = new Date(Date.now() - maxAgeDays * 24 * 60 * 60 * 1e3);
const candidates = index.entries.filter((entry) => {
if (entry.frequency < minFrequency) return false;
if (new Date(entry.last_seen) < cutoff) return false;
if (entry.stale) return false;
return true;
});
const filtered = [];
for (const candidate of candidates) {
const entry = await loadEntry(candidate.pattern_id, storeRoot);
if (!entry) continue;
if (options.stack_context && !stackMatches(entry.stack_contexts, options.stack_context)) {
continue;
}
filtered.push(entry);
}
return filtered.sort((a, b) => b.frequency - a.frequency).slice(0, limit);
}
async function prunePatterns(olderThanDays, storeRoot = defaultStoreRoot()) {
const index = await loadIndex(storeRoot);
const cutoff = new Date(Date.now() - olderThanDays * 24 * 60 * 60 * 1e3);
const toRemove = index.entries.filter((e) => new Date(e.last_seen) < cutoff);
for (const entry of toRemove) {
try {
const { unlink } = await import("fs/promises");
await unlink(entryPath(entry.pattern_id, storeRoot));
} catch {
}
}
index.entries = index.entries.filter((e) => new Date(e.last_seen) >= cutoff);
index.updated_at = (/* @__PURE__ */ new Date()).toISOString();
await saveIndex(index, storeRoot);
return toRemove.length;
}
async function loadIndex(storeRoot = defaultStoreRoot()) {
const indexFile = path.join(storeRoot, "index.json");
try {
const raw = await readFile(indexFile, "utf8");
const parsed = JSON.parse(raw);
if (typeof parsed.schema_version !== "number" || !Array.isArray(parsed.entries)) {
throw new Error("invalid index structure");
}
return parsed;
} catch {
return rebuildIndex(storeRoot);
}
}
async function loadEntry(patternId, storeRoot = defaultStoreRoot()) {
try {
const raw = await readFile(entryPath(patternId, storeRoot), "utf8");
return JSON.parse(raw);
} catch {
return null;
}
}
function entryPath(patternId, storeRoot) {
return path.join(storeRoot, "entries", `${patternId}.json`);
}
async function ensureStoreDir(storeRoot) {
await mkdir(path.join(storeRoot, "entries"), { recursive: true });
}
async function saveIndex(index, storeRoot) {
await ensureStoreDir(storeRoot);
await writeFile(
path.join(storeRoot, "index.json"),
JSON.stringify(index, null, 2) + "\n",
"utf8"
);
}
async function saveEntry(entry, storeRoot) {
await ensureStoreDir(storeRoot);
await writeFile(
entryPath(entry.pattern_id, storeRoot),
JSON.stringify(entry, null, 2) + "\n",
"utf8"
);
}
async function rebuildIndex(storeRoot) {
const entriesDir = path.join(storeRoot, "entries");
let files = [];
try {
files = await readdir(entriesDir);
} catch {
}
const entries = [];
for (const file of files) {
if (!file.endsWith(".json")) continue;
const id = file.replace(/\.json$/, "");
try {
const raw = await readFile(path.join(entriesDir, file), "utf8");
const entry = JSON.parse(raw);
entries.push({
pattern_id: entry.pattern_id,
subcategory: entry.subcategory,
frequency: entry.frequency,
last_seen: entry.last_seen,
stale: entry.stale
});
} catch {
engineLog("warn", `[defect-patterns] Skipping corrupt entry file: ${id}.json`);
}
}
return {
schema_version: DEFECT_PATTERN_SCHEMA_VERSION,
updated_at: (/* @__PURE__ */ new Date()).toISOString(),
entries
};
}
async function upsertPattern(finding, index, storeRoot) {
const existing = index.entries.find((e) => e.subcategory === finding.subcategory);
if (existing) {
const entry = await loadEntry(existing.pattern_id, storeRoot);
if (!entry) return;
applyFindingToEntry(finding, entry);
existing.frequency = entry.frequency;
existing.last_seen = entry.last_seen;
existing.stale = entry.stale;
await saveEntry(entry, storeRoot);
} else {
const entry = createEntryFromFinding(finding);
index.entries.push({
pattern_id: entry.pattern_id,
subcategory: entry.subcategory,
frequency: entry.frequency,
last_seen: entry.last_seen,
stale: entry.stale
});
await saveEntry(entry, storeRoot);
}
}
function createEntryFromFinding(finding) {
const now = finding.recorded_at;
return {
pattern_id: generatePatternId(finding.subcategory),
subcategory: finding.subcategory,
description: finding.description,
frequency: 1,
recency: now,
stack_contexts: [finding.stack_context],
example_obligations: finding.obligation_id ? [finding.description] : [],
example_files: finding.file_path ? [finding.file_path] : [],
severity_distribution: { critical: 0, major: 0, minor: 0, info: 0 },
first_seen: now,
last_seen: now,
stale: false
};
}
function applyFindingToEntry(finding, entry) {
entry.frequency += 1;
entry.last_seen = finding.recorded_at;
entry.recency = finding.recorded_at;
entry.stale = false;
if (!entry.stack_contexts.some(
(sc) => JSON.stringify(sc.frameworks.slice().sort()) === JSON.stringify(finding.stack_context.frameworks.slice().sort())
)) {
entry.stack_contexts.push(finding.stack_context);
}
if (finding.description && entry.example_obligations.length < EXAMPLE_CAP) {
if (!entry.example_obligations.includes(finding.description)) {
entry.example_obligations.push(finding.description);
}
}
if (finding.file_path && entry.example_files.length < EXAMPLE_CAP) {
if (!entry.example_files.includes(finding.file_path)) {
entry.example_files.push(finding.file_path);
}
}
}
function stackMatches(stored, query) {
if (query.frameworks.length === 0 && query.traits.length === 0) return true;
return stored.some(
(sc) => query.frameworks.some((f) => sc.frameworks.includes(f)) || query.traits.some((t) => sc.traits.includes(t))
);
}
function generatePatternId(subcategory) {
const slug = slugifyAscii(subcategory);
return `${slug}-${Date.now().toString(36)}`;
}
function markStaleEntries(index) {
const cutoff = new Date(Date.now() - STALENESS_DAYS * 24 * 60 * 60 * 1e3);
for (const entry of index.entries) {
entry.stale = new Date(entry.last_seen) < cutoff;
}
}
// src/core/constants/planning.ts
init_esm_shims();
var PLANNING_MANIFEST_VERSION = 1;
var PLAN_MODES = {
FULL: "full",
DELTA: "delta"
};
var PLANNING_LANES = {
FAST: "fast",
GRADUATED: "graduated",
FULL: "full"
};
var REQUIREMENT_TYPES = {
FUNCTIONAL: "functional",
NON_FUNCTIONAL: "non-functional",
CONSTRAINT: "constraint",
EDGE_CASE: "edge-case"
};
var PROOF_TYPES = {
AUTOMATED: "automated",
MANUAL: "manual",
VISUAL: "visual"
};
var CRITERION_STATUSES = {
UNCOVERED: "uncovered",
COVERED: "covered",
PARTIAL: "partial",
INDETERMINATE: "indeterminate"
};
var HEALTH_TIERS = {
STABLE: "stable",
MODERATE: "moderate",
FRAGILE: "fragile",
UNKNOWN: "unknown"
};
var ROLLBACK_CLASSES = {
SAFE: "safe",
NEEDS_MIGRATION: "needs-migration",
DESTRUCTIVE: "destructive"
};
// src/planning/module-health.ts
init_esm_shims();
var import_fast_glob = __toESM(require_out(), 1);
import { mkdir as mkdir2, readFile as readFile2, rename, writeFile as writeFile2 } from "fs/promises";
import { dirname, join } from "path";
function deriveHealthTier(metrics) {
const coverage = metrics.coverage_pct ?? null;
const defectFrequency = metrics.defect_frequency ?? null;
const contractStability = metrics.contract_stability ?? null;
if (coverage === null && defectFrequency === null && contractStability === null) {
return HEALTH_TIERS.UNKNOWN;
}
if (coverage !== null && coverage >= 80 && defectFrequency !== null && defectFrequency <= 2 && contractStability !== null && contractStability >= 0.85) {
return HEALTH_TIERS.STABLE;
}
if (coverage !== null && coverage >= 50 && defectFrequency !== null && defectFrequency <= 5) {
return HEALTH_TIERS.MODERATE;
}
return HEALTH_TIERS.FRAGILE;
}
async function readModuleHealth(root, moduleName) {
try {
const raw = await readFile2(moduleHealthPath(root, moduleName), "utf8");
return JSON.parse(raw);
} catch {
return null;
}
}
async function writeModuleHealth(root, moduleName, metrics) {
const profile = {
module: moduleName,
tier: deriveHealthTier(metrics),
metrics,
updated_at: (/* @__PURE__ */ new Date()).toISOString()
};
await writeModuleHealthProfile(root, profile);
return profile;
}
async function writeModuleHealthProfile(root, profile) {
const path2 = moduleHealthPath(root, profile.module);
await mkdir2(dirname(path2), { recursive: true });
const content = JSON.stringify(profile, null, 2) + "\n";
JSON.parse(content);
const temporaryPath = `${path2}.${process.pid}.${Date.now()}.tmp`;
await writeFile2(temporaryPath, content, "utf8");
await rename(temporaryPath, path2);
return profile;
}
async function readAllModuleHealth(root) {
const dir = join(root, PATHS.PLANNING_MODULE_HEALTH_DIR);
try {
const files = await (0, import_fast_glob.default)("**/*.json", { cwd: dir, onlyFiles: true });
const profiles = await Promise.all(
files.filter((file) => !file.split("/").includes("evidence")).map(async (file) => {
const raw = await readFile2(join(dir, file), "utf8");
return JSON.parse(raw);
})
);
return profiles.filter(isModuleHealthProfile).sort((left, right) => left.module.localeCompare(right.module));
} catch {
return [];
}
}
async function initializeModuleHealth(root, moduleName) {
const existing = await readModuleHealth(root, moduleName);
if (existing) {
return existing;
}
return writeModuleHealth(root, moduleName, {
coverage_pct: null,
defect_frequency: null,
contract_stability: null,
change_velocity: null
});
}
function moduleHealthPath(root, moduleName) {
return join(root, PATHS.PLANNING_MODULE_HEALTH_DIR, `${moduleName}.json`);
}
function isModuleHealthProfile(value) {
return typeof value.module === "string" && typeof value.tier === "string" && typeof value.metrics === "object" && value.metrics !== null && typeof value.updated_at === "string";
}
// src/planning/module-health-updater.ts
init_esm_shims();
var import_fast_glob2 = __toESM(require_out(), 1);
import { createHash, randomBytes } from "crypto";
import { existsSync } from "fs";
import { mkdir as mkdir3, readFile as readFile3, readdir as readdir2, rename as rename2, rm, writeFile as writeFile3 } from "fs/promises";
import { dirname as dirname2, join as join2, relative } from "path";
var LOOKBACK_DAYS = 90;
var MAX_PROCESSED_EVENT_IDS = 50;
async function syncModuleHealth(options) {
const acquired = await acquireLock(options.projectRoot);
if (!acquired) {
await writeAudit(options.projectRoot, {
action: "lock-contention-skip",
source: options.source ?? "provider-hook",
provider: options.provider,
detail: "Module health sync skipped because another updater owns the lock."
});
return { processed_events: 0, updated_profiles: [], skipped: true, reason: "locked" };
}
try {
await collectSessionEvidence(options);
const evidence = await readEvidence(options.projectRoot);
if (evidence.length === 0) {
return { processed_events: 0, updated_profiles: [], skipped: false };
}
const modules = await resolveKnownModules(options.projectRoot);
const consumed = await readConsumedEventIndex(options.projectRoot);
const updated = /* @__PURE__ */ new Set();
const staleEvidenceIds = /* @__PURE__ */ new Set();
let processed = 0;
for (const event of evidence) {
if (consumed.event_ids.includes(event.event_id)) {
staleEvidenceIds.add(event.event_id);
continue;
}
const affectedModules = resolveEvidenceModules(event, modules);
if (affectedModules.length === 0) {
await writeAudit(options.projectRoot, {
action: "evidence-ignored",
source: event.source,
provider: event.provider,
event_id: event.event_id,
detail: "Evidence could not be mapped to a stable module."
});
continue;
}
for (const moduleName of affectedModules) {
const result = await applyEvidenceToProfile(options.projectRoot, moduleName, event);
if (result === "updated" || result === "created") {
updated.add(moduleName);
}
}
consumed.event_ids.push(event.event_id);
staleEvidenceIds.add(event.event_id);
processed += 1;
}
if (processed > 0) {
await writeConsumedEventIndex(options.projectRoot, consumed);
}
for (const eventId of staleEvidenceIds) {
await rm(evidencePath(options.projectRoot, eventId), { force: true });
}
return {
processed_events: processed,
updated_profiles: [...updated].sort(),
skipped: false
};
} catch (error) {
await writeAudit(options.projectRoot, {
action: "updater-failure",
source: options.source ?? "provider-hook",
provider: options.provider,
/* c8 ignore next -- JavaScript I/O failures arrive as Error objects in supported runtimes. */
detail: error instanceof Error ? error.message : String(error)
});
if (options.silent) {
return {
processed_events: 0,
updated_profiles: [],
skipped: true,
reason: "failure"
};
}
throw error;
} finally {
await releaseLock(options.projectRoot);
}
}
function gatesThatPassed(results) {
return results.filter((result) => result.passed && result.outcome === void 0).map((result) => result.gate);
}
async function syncModuleHealthFromVerification(input) {
try {
const structured = input.verificationContext.structured_test_results ?? [];
const failedTests = structured.reduce((total, result) => total + result.summary.failed, 0);
const erroredTests = structured.reduce((total, result) => total + result.summary.errored, 0);
const passedTests = structured.reduce((total, result) => total + result.summary.passed, 0);
const gatesPassed = gatesThatPassed(input.results);
const gatesFailed = input.results.filter((result) => !result.passed).map((result) => result.gate);
const status = gatesFailed.length > 0 || failedTests > 0 || erroredTests > 0 ? "fail" : "pass";
const mutation = input.verificationContext.mutation_result;
const mutationSignal = mutation && mutation.kill_rate !== null && mutation.status !== "skipped" ? { kill_rate: mutation.kill_rate, confidence: mutation.confidence } : void 0;
const event = createEvidence({
source: "verification-gate",
provider: input.provider,
sessionId: input.sessionId,
affectedFiles: input.verificationContext.changed_files,
affectedModules: input.verificationContext.modules,
signals: {
tests: structured.length > 0 ? {
status,
passed: passedTests,
failed: failedTests,
errored: erroredTests
} : void 0,
verification: {
status,
gates_passed: gatesPassed,
gates_failed: gatesFailed
},
docs: {
doc_targets_total: input.verificationContext.stale_doc_targets.length,
doc_targets_missing: input.verificationContext.stale_doc_targets.length
},
...mutationSignal ? { mutation: mutationSignal } : {}
}
});
await persistEvidence(input.projectRoot, event);
return syncModuleHealth({
projectRoot: input.projectRoot,
source: "verification-gate",
provider: input.provider,
sessionId: input.sessionId,
silent: true
});
} catch (error) {
await writeAudit(input.projectRoot, {
action: "updater-failure",
source: "verification-gate",
provider: input.provider,
/* v8 ignore start -- String(error) branch for non-Error throws; all tested errors are Error instances */
detail: error instanceof Error ? error.message : String(error)
/* v8 ignore stop */
});
return {
processed_events: 0,
updated_profiles: [],
skipped: true,
reason: "failure"
};
}
}
function createEvidence(input) {
const affectedFiles = normalizeList(input.affectedFiles ?? []);
const affectedModules = normalizeList(input.affectedModules ?? []);
const signals = pruneSignals(input.signals ?? {});
const stablePayload = JSON.stringify({
source: input.source,
provider: input.provider ?? null,
session_id: input.sessionId ?? null,
affected_files: affectedFiles,
affected_modules: affectedModules,
signals
});
const digest = createHash("sha256").update(stablePayload).digest("hex").slice(0, 16);
return {
schema_version: 1,
event_id: `mh-${digest}`,
source: input.source,
...input.provider ? { provider: input.provider } : {},
...input.sessionId ? { session_id: input.sessionId } : {},
created_at: (/* @__PURE__ */ new Date()).toISOString(),
affected_files: affectedFiles,
affected_modules: affectedModules,
signals
};
}
async function persistEvidence(projectRoot, evidence) {
const path2 = evidencePath(projectRoot, evidence.event_id);
await mkdir3(dirname2(path2), { recursive: true });
await atomicWriteJson(path2, evidence);
}
async function readConsumedEventIndex(projectRoot) {
try {
const parsed = JSON.parse(
await readFile3(join2(projectRoot, PATHS.MODULE_HEALTH_CONSUMED_EVENTS), "utf8")
);
return {
schema_version: 1,
/* v8 ignore start -- defensive fallbacks for malformed persisted data; always valid schema in practice */
event_ids: Array.isArray(parsed.event_ids) ? [
...new Set(
parsed.event_ids.filter((value) => typeof value === "string")
)
] : [],
updated_at: typeof parsed.updated_at === "string" ? parsed.updated_at : (/* @__PURE__ */ new Date(0)).toISOString()
};
} catch {
return {
schema_version: 1,
event_ids: [],
updated_at: (/* @__PURE__ */ new Date(0)).toISOString()
};
}
}
async function writeConsumedEventIndex(projectRoot, index) {
await atomicWriteJson(join2(projectRoot, PATHS.MODULE_HEALTH_CONSUMED_EVENTS), {
schema_version: 1,
event_ids: [...new Set(index.event_ids)].sort(),
updated_at: (/* @__PURE__ */ new Date()).toISOString()
});
}
async function collectSessionEvidence(options) {
const changedFiles = await readChangedFiles(options.projectRoot);
if (changedFiles.length === 0) {
return;
}
await persistEvidence(
options.projectRoot,
createEvidence({
source: options.source ?? (options.preflight ? "preflight" : "provider-hook"),
provider: options.provider,
sessionId: resolveEvidenceSessionId(options),
affectedFiles: changedFiles,
signals: {}
})
);
}
function resolveEvidenceSessionId(options) {
if (options.sessionId !== void 0) {
return options.sessionId;
}
if (options.preflight === true || options.source !== void 0 && options.source !== "provider-hook" && options.source !== "session-artifact") {
return void 0;
}
return `auto-${process.pid}-${Date.now()}-${randomBytes(4).toString("hex")}`;
}
async function readChangedFiles(projectRoot) {
return normalizeList(await readGitChangedFiles(projectRoot));
}
async function readEvidence(projectRoot) {
const dir = join2(projectRoot, PATHS.MODULE_HEALTH_EVIDENCE_DIR);
try {
const files = await (0, import_fast_glob2.default)("*.json", { cwd: dir, onlyFiles: true });
const events = [];
for (const file of files.sort()) {
try {
const parsed = JSON.parse(await readFile3(join2(dir, file), "utf8"));
if (isEvidence(parsed)) {
events.push(parsed);
} else {
await writeAudit(projectRoot, {
action: "evidence-ignored",
source: "provider-hook",
detail: `${file} failed schema validation.`
});
}
} catch {
await writeAudit(projectRoot, {
action: "evidence-ignored",
source: "provider-hook",
detail: `${file} is unreadable JSON.`
});
}
}
return events;
} catch {
return [];
}
}
async function applyEvidenceToProfile(projectRoot, moduleName, event) {
const existing = await readProfileConservatively(projectRoot, moduleName, event);
if (existing?.evidence?.processed_event_ids?.includes(event.event_id)) {
return "skipped";
}
const base = existing ?? createUnknownProfile(moduleName);
const nextMetrics = mergeMetrics(base.metrics, event);
const tier = deriveHealthTier(nextMetrics);
const processed = [...base.evidence?.processed_event_ids ?? [], event.event_id].slice(
-MAX_PROCESSED_EVENT_IDS
);
const verificationStatus = event.signals.verification?.status ?? event.signals.tests?.status;
const next = {
...base,
schema_version: 2,
module: moduleName,
tier,
metrics: nextMetrics,
evidence: {
...base.evidence ?? {},
last_event_id: event.event_id,
...event.provider ? { last_provider: event.provider } : {},
...event.session_id ? { last_session_id: event.session_id } : {},
...verificationStatus ? { last_verification_status: verificationStatus } : {},
last_changed_files: event.affected_files.slice(0, 25),
processed_event_ids: processed
},
history: {
...base.history ?? {},
lookback_days: LOOKBACK_DAYS,
events_count: (base.history?.events_count ?? 0) + 1,
last_failure_at: isFailure(event) ? event.created_at : base.history?.last_failure_at ?? null,
last_success_at: isSuccess(event) ? event.created_at : base.history?.last_success_at ?? null
},
updated_at: (/* @__PURE__ */ new Date()).toISOString()
};
await writeModuleHealthProfile(projectRoot, next);
await writeAudit(projectRoot, {
action: existing ? "profile-updated" : "profile-created",
source: event.source,
provider: event.provider,
event_id: event.event_id,
detail: `${moduleName} tier=${next.tier}.`
});
return existing ? "updated" : "created";
}
async function readProfileConservatively(projectRoot, moduleName, event) {
const path2 = moduleHealthPath(projectRoot, moduleName);
try {
if (!existsSync(path2)) {
return null;
}
const raw = await readFile3(path2, "utf8");
return JSON.parse(raw);
} catch {
await rename2(path2, `${path2}.corrupt-${Date.now()}`).catch(() => void 0);
await writeAudit(projectRoot, {
action: "profile-repair-attempted",
source: event.source,
provider: event.provider,
event_id: event.event_id,
detail: `Preserved corrupt profile for ${moduleName}; writing repaired profile from evidence.`
});
return null;
}
}
function mergeMetrics(existing, event) {
const next = { ...existing };
const coverage = deriveCoverage(event);
if (coverage !== null) {
next.coverage_pct = coverage;
}
const mutationScore = deriveMutationScore(event);
if (mutationScore !== null) {
next.mutation_score = mutationScore;
}
const defectDelta = defectContribution(event);
if (defectDelta > 0) {
next.defect_frequency = (next.defect_frequency ?? 0) + defectDelta;
} else if (hasSuccessfulStructuredVerification(event) && next.defect_frequency === null) {
next.defect_frequency = 0;
}
const stability = deriveContractStability(existing.contract_stability ?? null, event);
if (stability !== null) {
next.contract_stability = stability;
}
if (event.affected_files.length > 0 || event.session_id) {
next.change_velocity = (next.change_velocity ?? 0) + 1;
}
return next;
}
function deriveCoverage(event) {
const testCoverage = event.signals.tests?.coverage_pct;
if (typeof testCoverage === "number") {
return clamp(testCoverage, 0, 100);
}
const compliance = event.signals.compliance;
if (typeof compliance?.covered_obligations === "number" && typeof compliance.total_obligations === "number" && compliance.total_obligations > 0) {
return clamp(compliance.covered_obligations / compliance.total_obligations * 100, 0, 100);
}
return null;
}
function deriveMutationScore(event) {
const mutation = event.signals.mutation;
if (typeof mutation?.kill_rate === "number" && mutation.confidence !== "lower") {
return clamp(mutation.kill_rate, 0, 100);
}
return null;
}
function defectContribution(event) {
const failedTests = event.signals.tests?.failed ?? 0;
const erroredTests = event.signals.tests?.errored ?? 0;
const failedGates = event.signals.verification?.gates_failed?.length ?? 0;
const criticalObligations = event.signals.compliance?.uncovered_critical ?? 0;
const defects = (event.signals.defects?.new ?? 0) + (event.signals.defects?.recurring ?? 0);
const scopeViolations = event.signals.scope?.scope_violations ?? 0;
return failedTests + erroredTests + failedGates + criticalObligations + defects + scopeViolations;
}
function deriveContractStability(current, event) {
if (isFailure(event)) {
return clamp((current ?? 0.8) - 0.1, 0, 1);
}
if (hasSuccessfulStructuredVerification(event)) {
const docsMissing = event.signals.docs?.doc_targets_missing ?? 0;
return docsMissing > 0 ? clamp((current ?? 0.85) - 0.05, 0, 1) : Math.max(current ?? 0, 0.9);
}
return current;
}
async function resolveKnownModules(projectRoot) {
const fromProfiles = (await readAllModuleHealth(projectRoot)).map((profile) => profile.module);
let fromDocs;
try {
fromDocs = (await readdir2(join2(projectRoot, PATHS.MODULES_DIR), { withFileTypes: true })).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
} catch {
fromDocs = [];
}
return [.../* @__PURE__ */ new Set([...fromProfiles, ...fromDocs])].sort((left, right) => {
return right.length - left.length;
});
}
function resolveEvidenceModules(event, knownModules) {
if (event.affected_modules.length > 0) {
return event.affected_modules;
}
const resolved = /* @__PURE__ */ new Set();
for (const file of event.affected_files) {
const normalized = normalizePath(file);
const known = knownModules.find((moduleName) => pathMatchesModule(normalized, moduleName));
if (known) {
resolved.add(known);
continue;
}
const fallback = fallbackModuleFromPath(normalized);
if (fallback) {
resolved.add(fallback);
}
}
return [...resolved].sort();
}
function pathMatchesModule(file, moduleName) {
const normalizedModule = normalizePath(moduleName);
return file === normalizedModule || file.startsWith(`${normalizedModule}/`) || file.includes(`/modules/${normalizedModule}/`) || file.includes(`/${normalizedModule}/`);
}
function fallbackModuleFromPath(file) {
const parts = file.split("/").filter(Boolean);
if (parts[0] === "src" && parts[1]) {
return parts[1];
}
if (parts[0] === "lib" && parts[1]) {
return parts[1];
}
if (parts[0] === "app" && parts[1]) {
return parts[1];
}
if (parts[0] === "tests" && parts[2]) {
return parts[2];
}
if (parts[0] === "docs" && parts[1] === "modules" && parts[2]) {
return parts[2];
}
return null;
}
async function acquireLock(projectRoot) {
try {
const lockPath = join2(projectRoot, PATHS.MODULE_HEALTH_LOCK);
await mkdir3(dirname2(lockPath), { recursive: true });
await mkdir3(lockPath, { recursive: false });
return true;
} catch {
return false;
}
}
async function releaseLock(projectRoot) {
await rm(join2(projectRoot, PATHS.MODULE_HEALTH_LOCK), { recursive: true, force: true });
}
async function writeAudit(projectRoot, event) {
const line = JSON.stringify({
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
subsystem: "module-health",
...event
});
const logPath = join2(projectRoot, PATHS.MODULE_HEALTH_LOG);
const auditPath = join2(projectRoot, PATHS.AUDIT_LOG);
await mkdir3(dirname2(logPath), { recursive: true });
await writeFile3(logPath, `${line}
`, { encoding: "utf8", flag: "a" });
await mkdir3(dirname2(auditPath), { recursive: true });
await writeFile3(auditPath, `${line}
`, { encoding: "utf8", flag: "a" });
}
function createUnknownProfile(moduleName) {
const metrics = {
coverage_pct: null,
defect_frequency: null,
contract_stability: null,
change_velocity: null,
mutation_score: null
};
return {
module: moduleName,
tier: deriveHealthTier(metrics),
metrics,
updated_at: (/* @__PURE__ */ new Date(0)).toISOString()
};
}
function isEvidence(value) {
return value?.schema_version === 1 && typeof value.event_id === "string" && typeof value.source === "string" && typeof value.created_at === "string" && Array.isArray(value.affected_files) && Array.isArray(value.affected_modules) && typeof value.signals === "object" && value.signals !== null;
}
function hasSuccessfulStructuredVerification(event) {
return event.signals.verification?.status === "pass" || event.signals.tests?.status === "pass";
}
function isFailure(event) {
return event.signals.verification?.status === "fail" || event.signals.tests?.status === "fail" || defectContribution(event) > 0;
}
function isSuccess(event) {
return hasSuccessfulStructuredVerification(event) && !isFailure(event);
}
function pruneSignals(signals) {
return JSON.parse(JSON.stringify(signals));
}
function normalizeList(values) {
return [...new Set(values.map(normalizePath).filter((value) => value.length > 0))].sort();
}
function normalizePath(value) {
return value.replace(/\\/g, "/").replace(/^\.\//u, "");
}
function evidencePath(projectRoot, eventId) {
return join2(projectRoot, PATHS.MODULE_HEALTH_EVIDENCE_DIR, `${eventId}.json`);
}
async function atomicWriteJson(path2, value) {
const content = JSON.stringify(value, null, 2) + "\n";
JSON.parse(content);
const temporaryPath = `${path2}.${process.pid}.${Date.now()}.tmp`;
await writeFile3(temporaryPath, content, "utf8");
await rename2(temporaryPath, path2);
}
function toProjectRelative(projectRoot, path2) {
return normalizePath(relative(projectRoot, path2));
}
function clamp(value, min, max) {
return Math.max(min, Math.min(max, Number(value.toFixed(2))));
}
// src/planning/manifest-parser.ts
init_esm_shims();
var import_yaml = __toESM(require_dist(), 1);
import { access, mkdir as mkdir4, readFile as readFile4, readdir as readdir3, rename as rename3, writeFile as writeFile4 } from "fs/promises";
import { createHash as createHash2 } from "crypto";
import { dirname as dirname3, join as join3 } from "path";
async function loadManifest(root, slug) {
const raw = await readFile4(join3(root, PATHS.PLANNING_MANIFESTS_DIR, `${slug}.yaml`), "utf8");
return import_yaml.default.parse(raw);
}
async function saveManifest(root, manifest) {
const target = join3(root, PATHS.PLANNING_MANIFESTS_DIR, `${manifest.slug}.yaml`);
const temp = `${target}.tmp`;
await mkdir4(dirname3(target), { recursive: true });
await writeFile4(temp, import_yaml.default.stringify(manifest), "utf8");
await rename3(temp, target);
return target;
}
async function manifestExists(root, slug) {
try {
await access(join3(root, PATHS.PLANNING_MANIFESTS_DIR, `${slug}.yaml`));
return true;
} catch {
return false;
}
}
async function listManifestSlugs(root) {
try {
const files = await readdir3(join3(root, PATHS.PLANNING_MANIFESTS_DIR));
return files.filter((file) => file.endsWith(".yaml")).map((file) => file.slice(0, -".yaml".length)).sort();
} catch {
return [];
}
}
function computeManifestHash(manifest) {
const canonical = stableStringify(manifest);
return `sha256:${createHash2("sha256").update(canonical).digest("hex")}`;
}
function stableStringify(value) {
if (Array.isArray(value)) {
return `[${value.map((entry) => stableStringify(entry)).join(",")}]`;
}
if (value && typeof value === "object") {
const entries = Object.entries(value).sort(
([left], [right]) => left.localeCompare(right)
);
return `{${entries.map(([key, entry]) => `${JSON.stringify(key)}:${stableStringify(entry)}`).join(",")}}`;
}
return JSON.stringify(value);
}
// src/pipeline/confidence-scorer.ts
init_esm_shims();
var WEIGHTS = {
deterministic: 1,
"deterministic:mcp": 1,
"deterministic:rag": 1,
"deterministic:graph": 1,
"deterministic:manifest": 1,
"llm-confirmed": 0.8,
"llm-overridden": 0.6,
"llm-guessed": 0.3,
"health-override": 1,
"history-corrected": 1,
"defect-floor": 1,
default: 0.1
};
var TOTAL_CLASSIFICATION_DIMENSIONS = 15;
function computeClassificationConfidence(resolutionMap) {
const entries = Object.values(resolutionMap).filter(
(value) => value !== void 0
);
if (entries.length === 0) {
return 0;
}
const weighted = entries.reduce((sum, source) => sum + (WEIGHTS[source] ?? 0.1), 0);
return Math.min(1, Math.round(weighted / TOTAL_CLASSIFICATION_DIMENSIONS * 100) / 100);
}
// src/pipeline/post-classifier.ts
init_esm_shims();
import { mkdir as mkdir5, readFile as readFile5, readdir as readdir4, writeFile as writeFile5 } from "fs/promises";
import { join as join4 } from "path";
var PostClassifier = class {
constructor(projectRoot) {
this.projectRoot = projectRoot;
}
projectRoot;
async adjust(classification, _preResult, resolutionMap) {
const laneBeforeOverride = selectWorkflowAwareLane(classification);
if (this.projectRoot) {
await syncModuleHealth({
projectRoot: this.projectRoot,
source: "preflight",
preflight: true,
silent: true
});
}
const healthProfiles = this.projectRoot ? await readAllModuleHealth(this.projectRoot) : [];
const affected = new Set(classification.affected_modules);
const relevantHealth = healthProfiles.filter((profile) => affected.has(profile.module));
let laneOverrideReason = null;
let complexity = classification.complexity;
let risk = classification.risk;
if (relevantHealth.some((profile) => profile.tier === "fragile")) {
laneOverrideReason = "Affected modules include fragile health tiers.";
risk = "high";
resolutionMap.risk = "health-override";
} else if (relevantHealth.length > 0 && relevantHealth.every((profile) => profile.tier === "stable") && classification.complexity === "trivial") {
laneOverrideReason = "Stable modules allow the fast lane for trivial work.";
}
const defectFloor = await this.computeRiskFloor(classification);
if (riskRank(defectFloor.risk_floor) > riskRank(risk)) {
risk = defectFloor.risk_floor;
resolutionMap.risk = "defect-floor";
}
const complexityAdjustment = await this.computeComplexityAdjustment(
classification.affected_modules
);
if (complexityAdjustment.adjustment !== 0) {
complexity = applyComplexityAdjustment(complexity, complexityAdjustment.adjustment);
resolutionMap.complexity = "history-corrected";
}
const highOverrideRate = Object.values(resolutionMap).filter((source) => source === "llm-overridden").length / Math.max(Object.keys(resolutionMap).length, 1) > 0.3;
await this.writeHistory(highOverrideRate);
return {
complexity,
risk,
lane_before_override: laneBeforeOverride,
lane_override_reason: laneOverrideReason,
risk_floor: defectFloor.risk_floor,
risk_floor_reason: defectFloor.risk_floor_reason,
complexity_adjustment: complexityAdjustment.adjustment,
complexity_adjustment_reason: complexityAdjustment.reason,
resolution_updates: {},
high_override_rate: highOverrideRate
};
}
async computeRiskFloor(classification) {
const { frequency, matchCount } = await this.readDefectStats(classification.affected_modules);
if (frequency > 10) {
return {
risk_floor: "high",
risk_floor_reason: "Defect history exceeds 10 relevant recurrences."
};
}
if (frequency > 5) {
return {
risk_floor: "medium",
risk_floor_reason: "Defect history exceeds 5 relevant recurrences."
};
}
if (matchCount > 3) {
return {
risk_floor: "medium",
risk_floor_reason: "More than 3 open defect patterns tracked for affected modules."
};
}
return { risk_floor: null, risk_floor_reason: null };
}
async readDefectStats(affectedModules) {
try {
const patterns = await queryPatterns({ min_frequency: 1, limit: 10 });
const matching = patterns.filter(
(entry) => entry.example_files.some(
(file) => affectedModules.some((modulePath) => file.replace(/\\/g, "/").includes(modulePath))
)
);
const frequency = matching.reduce((max, entry) => Math.max(max, entry.frequency), 0);
return { frequency, matchCount: matching.length };
} catch {
return { frequency: 0, matchCount: 0 };
}
}
async computeComplexityAdjustment(affectedModules) {
if (!this.projectRoot) {
return { adjustment: 0, reason: null };
}
const specsDir = join4(this.projectRoot, PATHS.PLANNING_MANIFESTS_DIR);
try {
const files = (await readdir4(specsDir)).filter(
(file) => file.endsWith(".plan-vs-actual.json")
);
const records = [];
for (const file of files) {
try {
const parsed = JSON.parse(await readFile5(join4(specsDir, file), "utf8"));
const touchesAffected = affectedModules.length === 0 || (parsed.unplanned_files ?? []).some(
(entry) => affectedModules.some((modulePath) => entry.includes(modulePath))
);
if (touchesAffected) {
records.push(parsed);
}
} catch {
}
}
if (records.length < 3) {
return { adjustment: 0, reason: null };
}
const lowAccuracy = records.filter((entry) => (entry.scope_accuracy_pct ?? 100) < 67).length;
const veryHighAccuracy = records.filter(
(entry) => (entry.scope_accuracy_pct ?? 0) > 200
).length;
if (lowAccuracy >= 3) {
return { adjustment: 1, reason: "Plan-vs-actual history shows repeated under-scoping." };
}
if (veryHighAccuracy >= 3) {
return { adjustment: -1, reason: "Plan-vs-actual history shows repeated over-estimation." };
}
} catch {
}
return { adjustment: 0, reason: null };
}
async writeHistory(highOverrideRate) {
if (!this.projectRoot) {
return;
}
const filePath = join4(this.projectRoot, PATHS.AGENCY_CACHE_DIR, "classification-history.json");
let entries;
try {
entries = JSON.parse(await readFile5(filePath, "utf8"));
} catch {
entries = [];
}
entries.push({ timestamp: (/* @__PURE__ */ new Date()).toISOString(), high_override_rate: highOverrideRate });
entries = entries.slice(-50);
await mkdir5(join4(this.projectRoot, PATHS.AGENCY_CACHE_DIR), { recursive: true });
await writeFile5(filePath, JSON.stringify(entries, null, 2) + "\n", "utf8");
}
};
function applyComplexityAdjustment(complexity, adjustment) {
const index = COMPLEXITY_LEVELS.indexOf(complexity);
const next = Math.max(0, Math.min(COMPLEXITY_LEVELS.length - 1, index + adjustment));
return COMPLEXITY_LEVELS[next];
}
function riskRank(risk) {
if (risk === "high") {
return 3;
}
if (risk === "medium") {
return 2;
}
if (risk === "low") {
return 1;
}
return 0;
}
function selectWorkflowAwareLane(classification) {
if (classification.workflow === "project-question") {
return "fast";
}
if (classification.workflow === "writing" || classification.workflow === "editing" || classification.workflow === "planning" || classification.workflow === "research") {
return "fast";
}
if (classification.workflow === "investigation") {
return "fast";
}
if (classification.workflow === "pentest" || classification.workflow === "pentest-retest") {
return "graduated";
}
if (classification.workflow === "migration") {
return "full";
}
if (classification.workflow === "bug-fix") {
return classification.complexity === "low" && classification.risk === "low" ? "fast" : "graduated";
}
if (classification.workflow === "feature-development") {
return classification.risk === "high" ? "full" : "graduated";
}
return selectLane(classification.complexity, classification.risk);
}
// src/pipeline/context-budget-estimator.ts
init_esm_shims();
function estimateContextBudgetHint(input) {
if (input.scope === "system-wide" || input.workflow === "migration" || input.workflow === "architecture-change") {
return "deep";
}
if (input.delta_candidate || input.scope === "multi-module") {
return "standard";
}
return "minimal";
}
// src/pipeline/delta-detector.ts
init_esm_shims();
async function detectDeltaCandidate(root, affectedModules) {
if (affectedModules.length === 0) {
return emptyResult();
}
const slugs = await listManifestSlugs(root);
let bestMatch = {
...emptyResult(),
overlap: 0
};
for (const slug of slugs) {
try {
const manifest = await loadManifest(root, slug);
const manifestModules = manifest.classification.affected_modules ?? [];
if (manifestModules.length === 0) {
continue;
}
const shared = affectedModules.filter((modulePath) => manifestModules.includes(modulePath));
const overlap = shared.length / Math.max(affectedModules.length, manifestModules.length, 1);
if (overlap >= 0.5 && overlap > bestMatch.overlap) {
bestMatch = {
delta_candidate: true,
base_manifest_slug: slug,
prior_requirement_count: manifest.requirement_graph.length,
prior_criterion_count: manifest.verification_matrix.length,
overlap
};
}
} catch {
}
}
return {
delta_candidate: bestMatch.delta_candidate,
base_manifest_slug: bestMatch.base_manifest_slug,
prior_requirement_count: bestMatch.prior_requirement_count,
prior_criterion_count: bestMatch.prior_criterion_count
};
}
function emptyResult() {
return {
delta_candidate: false,
base_manifest_slug: null,
prior_requirement_count: null,
prior_criterion_count: null
};
}
// src/pipeline/impact-resolver.ts
init_esm_shims();
function resolveImpacts(input) {
const request = input.requestText.toLowerCase();
const paths = input.modulePaths.map((entry) => entry.toLowerCase());
const databaseImpact = request.includes("data migration") ? "data-migration" : paths.some((entry) => entry.includes("migrations")) ? "schema-change" : request.includes("migration") || request.includes("schema") || request.includes("column") || request.includes("table") ? "schema-change" : request.includes("query") || request.includes("index") ? "query-change" : "none";
const apiImpact = request.includes("breaking api") || request.includes("breaking endpoint") ? "breaking-change" : paths.some((entry) => entry.includes("/routes") || entry.includes("/api")) ? request.includes("breaking") || request.includes("modify") || request.includes("update") ? "modified-endpoint" : "additive-endpoint" : request.includes("api") || request.includes("endpoint") || request.includes("route") ? request.includes("modify") || request.includes("update") ? "modified-endpoint" : "additive-endpoint" : "none";
const uiImpact = request.includes("redesign") ? "redesign" : paths.some((entry) => /pages|screens|views/.test(entry)) ? "new-screen" : paths.some((entry) => /components|widgets/.test(entry)) ? "new-component" : request.includes("screen") || request.includes("dashboard") || request.includes("page") ? "new-screen" : request.includes("component") || request.includes("button") || request.includes("form") ? "new-component" : "none";
const complianceSensitivity = /(compliance|gdpr|hipaa|pci|soc2|privacy)/.test(request) ? "high" : "none";
const customerFacingImpact = request.includes("customer") || uiImpact !== "none" ? "customer-visible" : "internal";
const dataSensitivity = request.includes("pii") ? "pii" : request.includes("payment") ? "financial" : request.includes("health") ? "health" : "none";
const reversibility = databaseImpact === "data-migration" || apiImpact === "breaking-change" ? "difficult" : "easily-reversible";
const pathBased = paths.length > 0;
const resolution_sources = {
database_impact: pathBased && paths.some((p) => p.includes("migrations")) ? "deterministic" : "deterministic",
api_impact: pathBased && paths.some((p) => p.includes("/routes") || p.includes("/api")) ? "deterministic" : "deterministic",
ui_impact: pathBased && paths.some((p) => /pages|screens|views|components|widgets/.test(p)) ? "deterministic" : "deterministic",
compliance_sensitivity: "deterministic",
customer_facing_impact: "deterministic",
reversibility: "deterministic",
data_sensitivity: "deterministic"
};
return {
database_impact: databaseImpact,
api_impact: apiImpact,
ui_impact: uiImpact,
compliance_sensitivity: complianceSensitivity,
customer_facing_impact: customerFacingImpact,
reversibility,
data_sensitivity: dataSensitivity,
resolution_sources
};
}
// src/pipeline/module-resolver.ts
init_esm_shims();
import { existsSync as existsSync2 } from "fs";
import { readdir as readdir5 } from "fs/promises";
import { basename, join as join5, relative as relative2 } from "path";
var PATH_REGEX = /\b(?:src|app|resources|database|routes|lib|tests|docs|packages)\/[A-Za-z0-9_./-]+\b/g;
var KNOWN_EXTENSIONS = /\.(tsx?|jsx?|vue|svelte|astro|php|dart|py|rb|go|rs|java|kt|cs|md|json|ya?ml)$/i;
var ModuleResolver = class {
constructor(root, profile) {
this.root = root;
this.profile = profile;
}
root;
profile;
async resolve(requestText) {
const explicit = await this.resolveExplicitPaths(requestText);
if (explicit.length > 0) {
return { modules: dedupeModules(explicit).slice(0, 8), source: "explicit-path" };
}
const symbols = await this.resolveSymbols(requestText);
if (symbols.length > 0) {
return { modules: dedupeModules(symbols).slice(0, 8), source: "symbol-index" };
}
const rag = await this.resolveRagMatches(requestText, explicit);
if (rag.length > 0) {
return { modules: dedupeModules(rag).slice(0, 8), source: "rag" };
}
const heuristics = this.resolveHeuristicModules(requestText);
return {
modules: dedupeModules(heuristics).slice(0, 8),
source: heuristics.length > 0 ? "stack-heuristic" : "default"
};
}
async resolveExplicitPaths(requestText) {
const matches = requestText.match(PATH_REGEX) ?? [];
const resolved = [];
for (const match of matches) {
const normalized = stripTrailingChars(match.replace(/\\/g, "/"), ".,:;!?");
const absolute = join5(this.root, normalized);
if (existsSync2(absolute)) {
resolved.push({
path: trimKnownExtension(normalized),
source: "explicit-path",
confidence: 1
});
continue;
}
const maybeResolved = await this.tryResolveByBasename(normalized);
if (maybeResolved) {
resolved.push(maybeResolved);
}
}
return resolved;
}
async tryResolveByBasename(candidate) {
const parent = join5(this.root, candidate.split("/").slice(0, -1).join("/"));
const leaf = basename(candidate);
try {
const entries = await readdir5(parent);
const match = entries.find((entry) => trimKnownExtension(entry) === trimKnownExtension(leaf));
if (!match) {
return null;
}
return {
path: trimKnownExtension(join5(relative2(this.root, parent), match).replace(/\\/g, "/")),
source: "explicit-path",
confidence: 0.95
};
} catch {
return null;
}
}
async resolveSymbols(requestText) {
const symbolTokens = Array.from(
new Set(
requestText.match(/\b[A-Z][A-Za-z0-9]+(?:Controller|Service|Model|Repository)\b/g) ?? []
)
);
if (symbolTokens.length === 0) {
return [];
}
const index = await new ChunkIndexManager(this.root).load();
if (!index) {
return [];
}
const matches = [];
for (const entry of index.entries) {
const exported = new Set(entry.chunks.flatMap((chunk) => chunk.exported_symbols));
if (symbolTokens.some((token) => exported.has(token))) {
matches.push({
path: trimKnownExtension(relative2(this.root, entry.source_file).replace(/\\/g, "/")),
source: "symbol-index",
confidence: 0.9
});
}
}
return matches;
}
async resolveRagMatches(requestText, explicit) {
if (!this.profile?.intelligence?.rag_enabled || explicit.length > 0) {
return [];
}
try {
const rag = new RagService(this.root);
const result = await rag.retrieveForEval({
keywords: requestText.split(/\s+/).slice(0, 8),
taskDescription: requestText
});
return result.retrieved_chunks.slice(0, 5).map((chunk) => ({
path: trimKnownExtension(relative2(this.root, chunk.source_file).replace(/\\/g, "/")),
source: "rag",
confidence: 0.7
})).filter((entry) => entry.path !== "");
} catch {
return [];
}
}
resolveHeuristicModules(requestText) {
const request = requestText.toLowerCase();
const framework = this.profile?.stack_profile?.frameworks?.[0] ?? "laravel";
const results = [];
if (/(migration|schema|table|column)/.test(request)) {
results.push({ path: "database/migrations", source: "stack-heuristic", confidence: 0.7 });
}
if (/(api|endpoint|route|controller)/.test(request)) {
for (const path2 of apiPrefixesForFramework(framework)) {
results.push({ path: path2, source: "stack-heuristic", confidence: 0.7 });
}
}
if (/(dashboard|page|screen|view)/.test(request)) {
for (const path2 of screenPrefixesForFramework(framework)) {
results.push({ path: path2, source: "stack-heuristic", confidence: 0.7 });
}
}
if (/(component|button|form|widget)/.test(request)) {
for (const path2 of componentPrefixesForFramework(framework)) {
results.push({ path: path2, source: "stack-heuristic", confidence: 0.7 });
}
}
return results;
}
};
function dedupeModules(modules) {
const byPath = /* @__PURE__ */ new Map();
for (const entry of modules) {
const current = byPath.get(entry.path);
if (!current || entry.confidence > current.confidence) {
byPath.set(entry.path, entry);
}
}
return Array.from(byPath.values());
}
function trimKnownExtension(filePath) {
return stripTrailingChars(filePath.replace(KNOWN_EXTENSIONS, ""), "/");
}
function apiPrefixesForFramework(framework) {
switch (framework) {
case "laravel":
return ["app/Http/Controllers", "routes"];
case "flutter":
return ["lib/services"];
default:
return ["src/api", "src/server"];
}
}
function screenPrefixesForFramework(framework) {
switch (framework) {
case "laravel":
return ["resources/views", "resources/js/pages"];
case "flutter":
return ["lib/screens"];
default:
return ["src/pages", "src/screens"];
}
}
function componentPrefixesForFramework(framework) {
switch (framework) {
case "laravel":
return ["resources/js/components", "app/View/Components"];
case "flutter":
return ["lib/widgets"];
default:
return ["src/components"];
}
}
// src/pipeline/scope-resolver.ts
init_esm_shims();
import { readFile as readFile6 } from "fs/promises";
import { join as join6, relative as relative3 } from "path";
var SCOPE_TIMEOUT_MS = 200;
var CORE_MODULE_PATTERN = /\b(?:src|lib)\/(?:core|shared|types|utils|common)\b/;
async function resolveScope(root, modulePaths) {
if (modulePaths.length === 0) {
return { scope: "single-module", scope_graph_depth: 0 };
}
if (modulePaths.length === 1) {
return { scope: "single-file", scope_graph_depth: 0 };
}
if (modulePaths.some((path2) => CORE_MODULE_PATTERN.test(path2))) {
return { scope: "system-wide", scope_graph_depth: 3 };
}
const ownRoots = new Set(modulePaths.map(topLevelModuleRoot));
if (ownRoots.size === 1) {
return { scope: "single-module", scope_graph_depth: 0 };
}
const externalRoots = await withTimeout(
scanExternalImportRoots(root, modulePaths, ownRoots),
SCOPE_TIMEOUT_MS,
/* @__PURE__ */ new Set()
);
const totalRoots = /* @__PURE__ */ new Set([...ownRoots, ...externalRoots]);
const depth = Math.min(externalRoots.size, 3);
const scope = totalRoots.size >= 4 ? "system-wide" : "multi-module";
return { scope, scope_graph_depth: depth };
}
async function scanExternalImportRoots(root, modulePaths, ownRoots) {
const external = /* @__PURE__ */ new Set();
await Promise.all(
modulePaths.slice(0, 8).map(async (modulePath) => {
try {
const content = await readFile6(join6(root, modulePath), "utf8");
const matches = Array.from(
content.matchAll(
/(?:import|export).+?from\s+['"]([^'"]+)['"]|require\(['"]([^'"]+)['"]\)/g
)
);
for (const match of matches) {
const importPath = (match[1] ?? match[2]).trim();
if (!importPath.startsWith(".") && !importPath.startsWith("@/")) {
continue;
}
const resolved = importPath.startsWith("@/") ? "src/" + importPath.slice(2) : importPath;
const importRoot = topLevelModuleRoot(resolved);
if (!ownRoots.has(importRoot)) {
external.add(importRoot);
}
}
} catch {
}
})
);
return external;
}
function topLevelModuleRoot(modulePath) {
const normalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
const parts = normalized.split("/");
return parts.slice(0, 2).join("/");
}
async function withTimeout(promise, ms, fallback) {
let timer;
try {
return await Promise.race([
promise,
new Promise((resolve) => {
timer = setTimeout(() => resolve(fallback), ms);
})
]);
} finally {
if (timer) {
clearTimeout(timer);
}
}
}
function toProjectRelativeModule(root, filePath) {
return relative3(root, filePath).replace(/\\/g, "/");
}
// src/pipeline/pre-classifier.ts
init_esm_shims();
var WORKFLOW_PATTERNS = [
{ workflow: "pentest-retest", priority: 250, patterns: ["pentest retest", "pentest-retest"] },
{
workflow: "pentest",
priority: 240,
patterns: [
"pentest",
"pen test",
"penetration test",
"security audit",
"security review",
"security test",
"security scan",
"vulnerability scan",
"for vulnerabilities"
]
},
{
workflow: "design-retest",
priority: 239,
patterns: ["design retest", "retest the design"]
},
{
workflow: "design-test",
priority: 238,
patterns: [
"design test",
"design audit",
"design system audit",
"audit the ui",
"audit our ui",
"ui audit",
"against the design system"
]
},
{
workflow: "health-retest",
priority: 245,
patterns: ["health retest", "health-retest", "codebase health retest"]
},
{
workflow: "codebase-health",
priority: 235,
patterns: [
"codebase health",
"code health",
"health check",
"health check-up",
"health audit",
"project's health",
"project health",
"audit my codebase",
"audit the codebase",
"find dead code",
"check for unused",
"cleanup audit"
]
},
{
workflow: "site-map-retest",
priority: 233,
patterns: ["site map retest", "site-map retest", "retest the site map", "retest site map"]
},
{
workflow: "site-map",
priority: 232,
patterns: [
"site map",
"create sitemap",
"update sitemap",
"generate sitemap",
"journey map",
"map the app",
"map this app",
"map our app",
"map the surfaces",
"navigation and journeys"
]
},
{
workflow: "rules-discovery",
priority: 231,
patterns: [
"discover rules",
"update our rules",
"audit our rules",
"are my rules out of date",
"rules discovery",
"new rules for our stack",
"rules are outdated"
]
},
{
workflow: "rules-generate",
priority: 229,
patterns: ["rules generate", "generate rule scripts", "generate the rule scripts"]
},
{
workflow: "rules-analyze",
priority: 228,
patterns: [
"rules analyze",
"rules analyse",
"analyze the rules",
"analyse the rules",
"analyze our rules",
"analyse our rules",
"rules can become scripts",
"rules could become scripts",
"rules into scripts"
]
},
{ workflow: "root-cause-analysis", priority: 230, patterns: ["root cause", "rca"] },
{
workflow: "module-documentation",
priority: 225,
patterns: ["module documentation", "module docs", "per module docs"]
},
{
workflow: "documentation-update",
priority: 200,
patterns: ["documentation", "docs", "documenation"]
},
{
workflow: "discovery",
priority: 190,
patterns: [
"rough idea",
"half baked idea",
"help me shape",
"shape this idea",
"shape the idea",
"shape an idea",
"shape my idea",
"not sure what it should look like"
]
},
{ workflow: "research", priority: 180, patterns: ["research", "investigate"] }
];
var CODE_CHANGE_PATTERNS = [
{ workflow: "cleanup", priority: 170, patterns: ["cleanup", "clean up"] },
{
workflow: "refactor",
priority: 150,
patterns: ["refactor", "refactors", "refactoring", "refactored"]
},
{
workflow: "bug-fix",
priority: 160,
patterns: ["fix", "fixes", "fixing", "fixed", "bug", "bugs"]
},
{
workflow: "feature-development",
priority: 140,
patterns: [
"implement",
"implements",
"implementing",
"implemented",
"build",
"builds",
"building",
"built",
"add",
"adds",
"adding",
"added",
"feature",
"features",
"develop",
"develops",
"developing",
"developed"
]
}
];
var PreClassifier = class {
constructor(projectRoot = process.cwd()) {
this.projectRoot = projectRoot;
}
projectRoot;
async classify(input) {
const resolutionMap = {};
const unresolved = /* @__PURE__ */ new Set();
const evidence = [];
const detectedForks = detectDecisionForks(input.request);
const workflow = resolveWorkflow(input.request, input.resolved_workflow?.workflow ?? null);
if (workflow !== void 0) {
resolutionMap.workflow = "deterministic";
evidence.push(`workflow:${workflow}`);
} else {
unresolved.add("workflow");
}
const moduleResolver = new ModuleResolver(this.projectRoot, input.profile);
const modulesPromise = moduleResolver.resolve(input.request);
const result = await withTimeout2(
(async () => {
const modules = await modulesPromise;
const modulePaths = modules.modules.map((entry) => entry.path);
if (modulePaths.length > 0) {
resolutionMap.affected_modules = modules.source === "rag" ? "deterministic:rag" : "deterministic";
evidence.push(`modules:${modules.source}`);
} else {
unresolved.add("affected_modules");
}
const [scope, impacts, delta, ruleTriggers] = await Promise.all([
resolveScope(this.projectRoot, modulePaths).catch(() => {
unresolved.add("scope");
return { scope: "single-module", scope_graph_depth: 0 };
}),
Promise.resolve(resolveImpacts({ requestText: input.request, modulePaths })),
detectDeltaCandidate(this.projectRoot, modulePaths).catch(() => {
unresolved.add("delta_candidate");
return {
delta_candidate: false,
base_manifest_slug: null,
prior_requirement_count: null,
prior_criterion_count: null
};
}),
matchRuleTriggers(this.projectRoot, modulePaths).catch(() => {
unresolved.add("matched_rule_triggers");
return [];
})
]);
resolutionMap.scope = unresolved.has("scope") ? "default" : "deterministic:graph";
resolutionMap.database_impact = impacts.resolution_sources.database_impact;
resolutionMap.api_impact = impacts.resolution_sources.api_impact;
resolutionMap.ui_impact = impacts.resolution_sources.ui_impact;
resolutionMap.compliance_sensitivity = impacts.resolution_sources.compliance_sensitivity;
resolutionMap.customer_facing_impact = impacts.resolution_sources.customer_facing_impact;
resolutionMap.reversibility = impacts.resolution_sources.reversibility;
resolutionMap.data_sensitivity = impacts.resolution_sources.data_sensitivity;
resolutionMap.delta_candidate = delta.delta_candidate ? "deterministic:manifest" : "default";
resolutionMap.context_budget_hint = "deterministic";
resolutionMap.matched_rule_triggers = ruleTriggers.length > 0 ? "deterministic" : "default";
const normalizedScope = modules.source === "stack-heuristic" && scope.scope === "single-file" ? "single-module" : scope.scope;
const contextBudgetHint = estimateContextBudgetHint({
scope: normalizedScope,
delta_candidate: delta.delta_candidate,
workflow: workflow ?? null
});
return {
resolved: {
workflow: workflow ?? void 0,
affected_modules: modulePaths,
affected_modules_source: modules.source,
scope: normalizedScope,
scope_graph_depth: scope.scope_graph_depth,
database_impact: impacts.database_impact,
api_impact: impacts.api_impact,
ui_impact: impacts.ui_impact,
compliance_sensitivity: impacts.compliance_sensitivity,
customer_facing_impact: impacts.customer_facing_impact,
reversibility: impacts.reversibility,
data_sensitivity: impacts.data_sensitivity,
delta_candidate: delta.delta_candidate,
base_manifest_slug: delta.base_manifest_slug,
prior_requirement_count: delta.prior_requirement_count,
prior_criterion_count: delta.prior_criterion_count,
context_budget_hint: contextBudgetHint,
matched_rule_triggers: ruleTriggers,
decision_category: detectedForks[0]?.category
},
hints: {},
unresolved: Array.from(unresolved),
resolution_map: resolutionMap,
evidence: [
...evidence,
...detectedForks.map((fork) => `decision-fork:${fork.category}:${fork.signal}`)
],
detected_forks: detectedForks
};
})(),
300,
{
resolved: {
workflow: workflow ?? void 0,
affected_modules: [],
affected_modules_source: "default",
scope: "single-module",
scope_graph_depth: 0,
database_impact: "none",
api_impact: "none",
ui_impact: "none",
compliance_sensitivity: "none",
customer_facing_impact: "internal",
reversibility: "easily-reversible",
data_sensitivity: "none",
delta_candidate: false,
base_manifest_slug: null,
prior_requirement_count: null,
prior_criterion_count: null,
context_budget_hint: "minimal",
matched_rule_triggers: [],
decision_category: detectedForks[0]?.category
},
hints: {},
unresolved: [
"affected_modules",
"scope",
"delta_candidate",
"database_impact",
"api_impact",
"ui_impact",
"matched_rule_triggers"
],
resolution_map: resolutionMap,
evidence: [
...evidence,
...detectedForks.map((fork) => `decision-fork:${fork.category}:${fork.signal}`),
"timeout"
],
detected_forks: detectedForks
}
);
return result;
}
};
function resolveWorkflow(requestText, routedWorkflow) {
if (routedWorkflow !== void 0 && routedWorkflow !== null) {
return routedWorkflow;
}
const normalized = normalizeText(requestText);
const codeWords = codeWordText(requestText);
const codeChange = highestMatch(
CODE_CHANGE_PATTERNS,
(pattern) => matchesWholeWord(codeWords, pattern)
);
const namedText = codeChange ? stripStageNames(normalized) : normalized;
const named = highestMatch(
WORKFLOW_PATTERNS,
(pattern) => namedText.includes(normalizeText(pattern))
);
if (named) {
return named;
}
if (isQuestionRoute(requestText) || hasCodeNegation(normalized) || isCreateArtifactAsk(normalized) || isAboutWorkPrompt(requestText)) {
return "project-question";
}
if (codeChange) {
return codeChange;
}
if (namesSourcePath(requestText) && usesPathEditVerb(normalized)) {
return "feature-development";
}
if (hasTrackerVerb(normalized) && !namesCode(requestText)) {
return "project-question";
}
return void 0;
}
var STAGE_NAME_PHRASES = ["documentation sync", "docs sync", "doc sync"];
function stripStageNames(normalized) {
return STAGE_NAME_PHRASES.reduce(
(text, phrase) => ` ${text} `.split(` ${phrase} `).join(" ").trim(),
normalized
);
}
function highestMatch(table, matches) {
return table.flatMap(
(entry) => entry.patterns.filter(matches).map((pattern) => ({ workflow: entry.workflow, priority: entry.priority, pattern }))
).sort((left, right) => right.priority - left.priority)[0]?.workflow;
}
function matchesWholeWord(normalized, pattern) {
return ` ${normalized} `.includes(` ${normalizeText(pattern)} `);
}
var QUESTION_ANYWHERE_LEADS = /* @__PURE__ */ new Set([
"how",
"where",
"what",
"whats",
"why",
"which",
"explain",
"example"
]);
var CODE_VERBS = /* @__PURE__ */ new Set([
"fix",
"fixes",
"fixing",
"fixed",
"add",
"adds",
"adding",
"added",
"implement",
"implements",
"implementing",
"implemented",
"build",
"builds",
"building",
"built",
"refactor",
"refactors",
"refactoring",
"refactored",
"change",
"changes",
"changing",
"changed",
"update",
"updates",
"updating",
"updated",
"remove",
"removes",
"removing",
"removed",
"rename",
"renames",
"renaming",
"renamed",
"migrate",
"migrates",
"migrating",
"migrated"
]);
var PATH_EDIT_VERBS = /* @__PURE__ */ new Set([
...CODE_VERBS,
"make",
"makes",
"making",
"replace",
"replaces",
"replacing",
"move",
"moves",
"moving",
"extract",
"extracts",
"extracting",
"convert",
"converts",
"converting",
"delete",
"deletes",
"deleting",
"rewrite",
"rewrites",
"rewriting"
]);
function usesPathEditVerb(normalized) {
return tokensOf(normalized).some((token) => PATH_EDIT_VERBS.has(token));
}
var POLITE_LEAD_INS = ["can you", "could you", "would you", "please", "let s"];
var DEVELOP_LEADS = /* @__PURE__ */ new Set(["develop", "develops"]);
function isQuestionRoute(requestText) {
const normalized = normalizeText(requestText);
const tokens = normalized.length > 0 ? normalized.split(" ") : [];
const interrogative = tokens.some((token) => QUESTION_ANYWHERE_LEADS.has(token)) || normalized.startsWith("in short") || normalized.includes("show me") || /\?\s*$/.test(requestText);
return interrogative && !isPoliteCodeRequest(normalized);
}
function isPoliteCodeRequest(normalized) {
const tokens = normalized.length > 0 ? normalized.split(" ") : [];
if (tokens[0] && (CODE_VERBS.has(tokens[0]) || DEVELOP_LEADS.has(tokens[0]))) {
return true;
}
return POLITE_LEAD_INS.some((lead) => {
const next = normalized.split(`${lead} `)[1]?.split(" ")[0];
return next !== void 0 && CODE_VERBS.has(next);
});
}
var CODE_NEGATIONS = [
"no code changes",
"no code change",
"no code",
"do not code",
"dont code",
"without changing",
"not to code"
];
function hasCodeNegation(normalized) {
return CODE_NEGATIONS.some((phrase) => normalized.includes(normalizeText(phrase)));
}
var CREATE_VERBS = ["create", "file", "open", "write", "draft"];
var ARTIFACT_NOUNS = [
["issue"],
["issues"],
["ticket"],
["tickets"],
["bug", "report"],
["bug", "reports"],
["write", "up"],
["write", "ups"]
];
var LEADING_CODE_VERBS = /* @__PURE__ */ new Set([
"fix",
"fixes",
"implement",
"implements",
"build",
"builds",
"refactor",
"refactors",
"add",
"adds",
"develop",
"develops"
]);
var NEGATION_WORDS = /* @__PURE__ */ new Set(["not", "dont", "never"]);
var NEGATION_FILLERS = /* @__PURE__ */ new Set(["actually", "even", "ever", "go", "just", "really", "to", "yet"]);
var VERB_TO_NOUN_REACH = 4;
var NEVER_TICKET_PREFIXES = /* @__PURE__ */ new Set([
"a",
"an",
"about",
"after",
"and",
"at",
"before",
"by",
"for",
"from",
"in",
"of",
"on",
"or",
"per",
"the",
"to",
"until",
"with"
]);
function startsWithLeadingCodeVerb(tokens) {
if (LEADING_CODE_VERBS.has(tokens[0] ?? "")) {
return true;
}
return tokens[0] === "work" && tokens[1] === "on";
}
function isNegationAt(tokens, index) {
const token = tokens[index];
if (token === void 0) {
return false;
}
return NEGATION_WORDS.has(token) || token === "t" && tokens[index - 1] === "don";
}
function isNegatedAt(tokens, index) {
if (isNegationAt(tokens, index - 1)) {
return true;
}
if (NEGATION_FILLERS.has(tokens[index - 1] ?? "") && isNegationAt(tokens, index - 2)) {
return true;
}
return tokens[index - 3] === "no" && tokens[index - 2] === "need" && tokens[index - 1] === "to";
}
function isNumberToken(token) {
return token !== void 0 && /^\d+$/.test(token);
}
function namesExistingTicket(tokens, afterNoun) {
const next = tokens[afterNoun];
if (isNumberToken(next)) {
return true;
}
return next !== void 0 && !NEVER_TICKET_PREFIXES.has(next) && /^[a-z]+$/.test(next) && isNumberToken(tokens[afterNoun + 1]);
}
function nounLengthAt(tokens, index) {
const noun = ARTIFACT_NOUNS.find(
(words) => words.every((word, offset) => tokens[index + offset] === word)
);
return noun?.length ?? 0;
}
function asksForArtifactFrom(tokens, verbIndex) {
const last = Math.min(verbIndex + VERB_TO_NOUN_REACH, tokens.length - 1);
for (let index = verbIndex; index <= last; index += 1) {
const length = nounLengthAt(tokens, index);
if (length > 0 && !namesExistingTicket(tokens, index + length)) {
return true;
}
}
return false;
}
function isCreateArtifactAsk(normalized) {
const tokens = tokensOf(normalized);
if (startsWithLeadingCodeVerb(tokens)) {
return false;
}
const asked = tokens.some(
(token, index) => CREATE_VERBS.includes(token) && !isNegatedAt(tokens, index) && asksForArtifactFrom(tokens, index)
);
if (!asked) {
return false;
}
const alsoImplements = /\b(implement|and (?:fix|add|build|change|update))\b/.test(normalized);
return !alsoImplements;
}
var TRACKER_NOUNS = /* @__PURE__ */ new Set(["issue", "issues", "ticket", "tickets", "pr", "prs"]);
var TRACKER_NOUN_PHRASES = ["pull request", "pull requests"];
var NOUN_OR_VERB_TRACKER_WORDS = /* @__PURE__ */ new Set(["draft", "drafts", "drafted", "rewrite", "rewrites"]);
var SOFT_WORK_NOUNS = /* @__PURE__ */ new Set(["report", "reports", "research", "plan", "plans", "doc", "docs"]);
var TRACKER_TARGETS = /* @__PURE__ */ new Set(["github", "jira", "linear"]);
var TRACKER_VERBS = /* @__PURE__ */ new Set([
"post",
"posts",
"posted",
"posting",
"repost",
"file",
"files",
"filed",
"filing",
"link",
"links",
"linked",
"linking",
"recheck",
"rechecks",
"rechecked",
"rechecking",
"confirm",
"confirms",
"confirmed",
"confirming",
"reconfirm",
"reconfirms",
"reconfirmed",
"reconfirming"
]);
var GENERAL_WORK_VERBS = /* @__PURE__ */ new Set([
"draft",
"drafts",
"drafted",
"drafting",
"update",
"updates",
"updated",
"updating",
"rewrite",
"rewrites",
"rewrote",
"rewritten",
"rewriting",
"check",
"checks",
"checked",
"checking"
]);
var VERB_LEADS = /* @__PURE__ */ new Set([
"please",
"pls",
"and",
"then",
"or",
"to",
"can",
"could",
"would",
"will",
"should",
"also",
"just",
"now",
"let",
"s",
"ll",
"you",
"i",
"we",
"yes",
"yeah",
"yep",
"ok",
"okay",
"sure",
"great",
"perfect",
"alright",
"thanks"
]);
var ADD_TO_RE = new RegExp(
String.raw`\b(?:add|adds|added|adding)\b.*\bto (?:(?:the|this|that|a|an|my|our|your) )?(?:` + [...TRACKER_NOUN_PHRASES, ...TRACKER_NOUNS, ...NOUN_OR_VERB_TRACKER_WORDS].join("|") + String.raw`)\b`
);
var CODE_SURFACE_NOUNS = /* @__PURE__ */ new Set([
"page",
"pages",
"screen",
"button",
"component",
"endpoint",
"api",
"function",
"method",
"class",
"field",
"column",
"form",
"modal",
"footer",
"header",
"navbar",
"sidebar",
"route",
"query",
"schema",
"test",
"tests",
"bug",
"error",
"crash",
"feature",
"export",
"import",
"selector",
"renders",
"mobile",
"desktop",
"css",
"layout"
]);
var LABEL_PAIR_RE = /\blabel(?:s|ed|led)? [a-z0-9]+/g;
var STRONG_CODE_VERB_RE = /\b(?:fix|fixes|fixing|fixed|implement|implements|implementing|implemented|build|builds|building|built|refactor|refactors|refactoring|refactored|develop|develops|developing|developed)\b/;
var SOURCE_PATH_RE = /\b(?:src|lib|app|runtime|tests)\/|\.(?:ts|tsx|js|jsx|mjs|cjs|py|php|rb|go|rs|java|kt|swift|cs|vue|svelte|dart)\b/i;
function namesSourcePath(requestText) {
return SOURCE_PATH_RE.test(requestText);
}
function namesCode(requestText) {
const codeWords = codeWordText(requestText);
if (namesSourcePath(requestText) || STRONG_CODE_VERB_RE.test(codeWords)) {
return true;
}
const withoutLabels = codeWords.replace(LABEL_PAIR_RE, " ").trim();
return withoutLabels.split(/\s+/).some((token) => CODE_SURFACE_NOUNS.has(token));
}
function tokensOf(normalized) {
return normalized.length > 0 ? normalized.split(" ") : [];
}
function inVerbPosition(tokens, index) {
return index === 0 || VERB_LEADS.has(String(tokens[index - 1]));
}
function usesVerbFrom(tokens, verbs) {
return tokens.some((token, index) => verbs.has(token) && inVerbPosition(tokens, index));
}
function hasTrackerVerb(normalized) {
return usesVerbFrom(tokensOf(normalized), TRACKER_VERBS) || ADD_TO_RE.test(normalized);
}
function hasTrackerNoun(normalized) {
const tokens = tokensOf(normalized);
return tokens.some(
(token, index) => TRACKER_NOUNS.has(token) || NOUN_OR_VERB_TRACKER_WORDS.has(token) && !inVerbPosition(tokens, index)
) || TRACKER_NOUN_PHRASES.some((phrase) => matchesWholeWord(normalized, phrase));
}
function isAboutWorkPrompt(requestText) {
const normalized = normalizeText(requestText);
if (namesCode(requestText)) {
return false;
}
const tokens = tokensOf(normalized);
const trackerNoun = hasTrackerNoun(normalized);
const target = tokens.some((token) => TRACKER_TARGETS.has(token));
const codeWords = codeWordText(requestText);
const codeKeyword = CODE_CHANGE_PATTERNS.some(
(entry) => entry.patterns.some((pattern) => matchesWholeWord(codeWords, pattern))
);
if (codeKeyword && !trackerNoun && !target) {
return false;
}
const trackerVerb = hasTrackerVerb(normalized);
const workVerb = trackerVerb || usesVerbFrom(tokens, GENERAL_WORK_VERBS);
if (trackerNoun) {
return workVerb;
}
const softNoun = tokens.some((token) => SOFT_WORK_NOUNS.has(token));
return softNoun && (trackerVerb || target && workVerb);
}
function codeWordText(requestText) {
return normalizeText(requestText.toLowerCase().replace(/\b[a-z0-9]+(?:-[a-z0-9]+)+\b/g, " "));
}
function normalizeText(value) {
return value.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim().replace(/\s+/g, " ");
}
async function withTimeout2(promise, ms, fallback) {
let timer;
try {
return await Promise.race([
promise,
new Promise((resolve) => {
timer = setTimeout(() => resolve(fallback), ms);
})
]);
} finally {
if (timer) {
clearTimeout(timer);
}
}
}
// src/pipeline/llm-skip-evaluator.ts
init_esm_shims();
var FAST_LANE_WORKFLOWS = /* @__PURE__ */ new Set([
"bug-fix",
"cleanup",
"documentation-update",
"editing",
"investigation",
"planning",
"project-question",
"research",
"test-improvement",
"writing"
]);
function shouldSkipLlm(preResult, confidence, requestText, resolutionMap) {
const normalized = requestText.toLowerCase();
if (normalized.includes("?") || normalized.includes("maybe") || normalized.includes("possibly")) {
return false;
}
const workflow = preResult.resolved.workflow ?? null;
const modulesSource = preResult.resolved.affected_modules_source ?? "";
const scopeSource = resolutionMap.scope;
const impactsResolved = resolutionMap.database_impact !== void 0 && resolutionMap.api_impact !== void 0 && resolutionMap.ui_impact !== void 0;
const ruleTriggers = preResult.resolved.matched_rule_triggers ?? [];
const sensitiveTriggers = ruleTriggers.some(
(trigger) => /(security|auth|compliance|privacy|payment|gdpr|secret)/i.test(trigger)
);
return confidence >= 0.85 && resolutionMap.workflow === "deterministic" && /explicit-path|symbol-index/.test(modulesSource) && scopeSource === "deterministic:graph" && impactsResolved && workflow !== null && FAST_LANE_WORKFLOWS.has(workflow) && !sensitiveTriggers && preResult.resolved.delta_candidate !== true;
}
// src/pipeline/classifier.ts
init_esm_shims();
// src/session/active-implementation.ts
init_esm_shims();
import { existsSync as existsSync3 } from "fs";
import { mkdir as mkdir6, readFile as readFile7, writeFile as writeFile6 } from "fs/promises";
import { dirname as dirname4, join as join7 } from "path";
var CONTINUITY_DOWNGRADE_WORKFLOWS = /* @__PURE__ */ new Set([
"project-question",
"research",
"writing",
"editing",
"planning",
"content-update",
"documentation-update",
"ticket-refinement"
]);
var EXPLICIT_EXPLANATION_ONLY_PATTERNS = [
/\b(?:explain|clarify|describe)\b.*\b(?:only|just)\b/i,
/\b(?:only|just)\b.*\b(?:explain|clarify|describe)\b/i,
/\bwalk me through\b.*\b(?:only|just)\b/i,
/\b(?:no|without)\s+(?:code\s+changes?|implementation|edits?)\b/i,
/\bdo not\s+(?:change|edit|implement|modify)\b/i
];
async function readActiveImplementationSession(projectRoot) {
const target = join7(projectRoot, PATHS.ACTIVE_IMPLEMENTATION_SESSION);
if (!existsSync3(target)) {
return null;
}
try {
const raw = await readFile7(target, "utf8");
const parsed = JSON.parse(raw);
if (!isActiveImplementationSessionArtifact(parsed)) {
return null;
}
return parsed;
} catch {
return null;
}
}
function applyActiveImplementationSession(requestText, classification, session, resolutionMap) {
const continuityCandidate = classification.workflow !== null && CONTINUITY_DOWNGRADE_WORKFLOWS.has(classification.workflow);
const explicitExplanationOnly = isExplicitExplanationOnlyIntent(requestText);
if (session === null || !session.active || session.workflow === null || classification.workflow === null || !continuityCandidate || explicitExplanationOnly) {
return {
resumed: false,
classification: {
...classification,
resumed_from_session: false,
resume_lane: null,
workflow_continuity_reason: session !== null && session.active && session.workflow !== null && continuityCandidate && explicitExplanationOnly ? `Allowed transition from active implementation workflow "${session.workflow}" to "${classification.workflow}" because the follow-up explicitly requested explanation-only guidance.` : null
}
};
}
if (resolutionMap) {
Object.assign(resolutionMap, {
workflow: "session-resume",
...session.scope ? { scope: "session-resume" } : {},
...session.affected_modules.length > 0 ? { affected_modules: "session-resume" } : {}
});
}
return {
resumed: true,
classification: {
...classification,
workflow: session.workflow,
workflow_source: "active-session",
workflow_reason: `Resumed active implementation workflow "${session.workflow}" because verification or documentation work is still unresolved.`,
scope: session.scope ?? classification.scope,
affected_modules: session.affected_modules.length > 0 ? [...session.affected_modules] : classification.affected_modules,
resumed_from_session: true,
resume_lane: session.lane,
workflow_continuity_reason: "Active implementation session remained open, so the follow-up stayed on the implementation lane."
}
};
}
function isExplicitExplanationOnlyIntent(requestText) {
const trimmed = requestText.trim();
return EXPLICIT_EXPLANATION_ONLY_PATTERNS.some((pattern) => pattern.test(trimmed));
}
function isActiveImplementationSessionArtifact(value) {
if (typeof value !== "object" || value === null) {
return false;
}
const candidate = value;
return candidate.version === 1 && typeof candidate.updated_at === "string" && typeof candidate.active === "boolean" && Array.isArray(candidate.changed_files) && Array.isArray(candidate.affected_modules) && Array.isArray(candidate.unresolved_items);
}
// src/pipeline/classifier.ts
var RequestClassifier = class {
projectRoot;
constructor(options = {}) {
this.projectRoot = options.projectRoot;
}
async classify(input) {
const requestText = input.request.trim();
const preResult = await new PreClassifier(this.projectRoot).classify({
request: requestText,
profile: input.profile,
resolved_workflow: input.resolved_workflow
});
const resolutionMap = { ...preResult.resolution_map };
const baseConfidence = computeClassificationConfidence(resolutionMap);
const deterministicOnly = shouldSkipLlm(preResult, baseConfidence, requestText, resolutionMap);
const initialClassification = deterministicOnly ? buildFromPreResult(input, preResult, resolutionMap) : runReducedScopeClassification(input, preResult, resolutionMap);
const activeSession = this.projectRoot ? await readActiveImplementationSession(this.projectRoot) : null;
const resumed = applyActiveImplementationSession(
requestText,
initialClassification,
activeSession,
resolutionMap
);
const baseClassification = resumed.classification;
const enrichedConfidence = computeClassificationConfidence(resolutionMap);
const adjustments = await new PostClassifier(this.projectRoot).adjust(
baseClassification,
preResult,
resolutionMap
);
const analyticsTag = this.resolveAnalyticsTag(baseClassification.workflow);
return {
...baseClassification,
...analyticsTag ? { analytics_tag: analyticsTag } : {},
complexity: adjustments.complexity,
risk: adjustments.risk,
classification_confidence: enrichedConfidence,
resolution_map: resolutionMap,
lane_before_override: adjustments.lane_before_override,
lane_override_reason: adjustments.lane_override_reason,
risk_floor: adjustments.risk_floor,
risk_floor_reason: adjustments.risk_floor_reason,
complexity_adjustment: adjustments.complexity_adjustment,
complexity_adjustment_reason: adjustments.complexity_adjustment_reason,
delta_candidate: preResult.resolved.delta_candidate,
base_manifest_slug: preResult.resolved.base_manifest_slug,
prior_requirement_count: preResult.resolved.prior_requirement_count,
prior_criterion_count: preResult.resolved.prior_criterion_count,
context_budget_hint: preResult.resolved.context_budget_hint,
affected_modules_source: preResult.resolved.affected_modules_source,
scope_graph_depth: preResult.resolved.scope_graph_depth,
matched_rule_triggers: preResult.resolved.matched_rule_triggers,
resumed_from_session: baseClassification.resumed_from_session,
resume_lane: baseClassification.resume_lane,
workflow_continuity_reason: baseClassification.workflow_continuity_reason
};
}
resolveAnalyticsTag(workflow) {
if (!this.projectRoot) {
return void 0;
}
try {
const flagEnabled = resolveFrameworkConfig(this.projectRoot).features.analytics_instrumentation;
if (!flagEnabled) {
return void 0;
}
return resolveAnalyticsGate({
projectRoot: this.projectRoot,
flagEnabled: true,
changeIsFeatureShaped: workflow === "feature-development"
}).status;
} catch {
return void 0;
}
}
};
function buildFromPreResult(input, preResult, resolutionMap) {
const requestText = input.request.trim();
const request = requestText.toLowerCase();
const workflow = preResult.resolved.workflow ?? input.resolved_workflow?.workflow ?? null;
const targetCapability = inferTargetCapability(request, workflow);
const domain = inferDomain(targetCapability, input.profile);
const stack = input.profile !== void 0 ? getPrimaryStack(input.profile) : inferStack(targetCapability);
const databaseImpact = preResult.resolved.database_impact ?? inferDatabaseImpact(request);
const apiImpact = preResult.resolved.api_impact ?? inferApiImpact(request);
const uiImpact = preResult.resolved.ui_impact ?? inferUiImpact(request);
const trivialSingleFile = inferTrivialSingleFile(requestText);
const complexity = inferComplexity(
request,
workflow,
databaseImpact,
apiImpact,
uiImpact,
trivialSingleFile
);
const risk = inferRisk(workflow, complexity, databaseImpact, apiImpact);
const scope = preResult.resolved.scope ?? inferScope(workflow, complexity, trivialSingleFile);
const capabilityGap = inferCapabilityGap(targetCapability, input.profile);
resolutionMap.complexity ??= "default";
resolutionMap.risk ??= "default";
resolutionMap.certainty ??= "default";
resolutionMap.output_type ??= "default";
return {
request_text: requestText,
domain,
stack,
target_capability: targetCapability,
capability_gap: capabilityGap,
workflow,
custom_workflow_name: input.resolved_workflow?.custom_workflow_name ?? null,
workflow_source: input.resolved_workflow?.workflow_source ?? "none",
workflow_reason: input.resolved_workflow?.workflow_reason ?? null,
matched_rule: input.resolved_workflow?.matched_rule ?? null,
complexity,
risk,
scope,
affected_modules: preResult.resolved.affected_modules && preResult.resolved.affected_modules.length > 0 ? preResult.resolved.affected_modules : inferModules(requestText, stack),
process_depth: complexity === "high" || complexity === "very-high" ? "full lane" : complexity === "medium" ? "graduated lane" : "fast lane",
certainty: request.includes("?") ? "partially-defined" : "well-defined",
output_type: inferOutputType(workflow),
database_impact: databaseImpact,
ui_impact: uiImpact,
api_impact: apiImpact,
compliance_sensitivity: preResult.resolved.compliance_sensitivity ?? (request.includes("compliance") || request.includes("gdpr") ? "high" : "none"),
customer_facing_impact: preResult.resolved.customer_facing_impact ?? (request.includes("customer") || uiImpact !== "none" ? "customer-visible" : "internal"),
reversibility: preResult.resolved.reversibility ?? (databaseImpact === "data-migration" || apiImpact === "breaking-change" ? "difficult" : "easily-reversible"),
data_sensitivity: preResult.resolved.data_sensitivity ?? (request.includes("pii") ? "pii" : request.includes("payment") ? "financial" : "none")
};
}
function runReducedScopeClassification(input, preResult, resolutionMap) {
const result = buildFromPreResult(input, preResult, resolutionMap);
for (const dimension of [
"workflow",
"affected_modules",
"scope",
"database_impact",
"api_impact",
"ui_impact",
"compliance_sensitivity",
"customer_facing_impact",
"reversibility",
"data_sensitivity"
]) {
if (resolutionMap[dimension]?.startsWith("deterministic")) {
resolutionMap[dimension] = "llm-confirmed";
}
}
resolutionMap.complexity = "llm-guessed";
resolutionMap.risk = "llm-guessed";
resolutionMap.certainty = "llm-guessed";
resolutionMap.output_type = "llm-confirmed";
return result;
}
function inferTargetCapability(request, workflow) {
if (workflow === "pentest" || workflow === "pentest-retest") {
return "security";
}
if (workflow === "documentation-update" || workflow === "project-question" || workflow === "writing" || workflow === "editing" || workflow === "planning" || workflow === "research") {
return "content";
}
if (workflow === null) {
if (request.includes("pentest") || request.includes("security")) {
return "security";
}
if (request.includes("documentation") || request.includes("content") || request.includes("docs")) {
return "content";
}
}
return "coding";
}
function inferDomain(targetCapability, profile) {
if (profile !== void 0) {
const stack = getPrimaryStack(profile);
if (stack !== "short-video") {
return "coding";
}
}
return targetCapability === "content" ? "content" : "coding";
}
function inferStack(targetCapability) {
return targetCapability === "content" ? "short-video" : "laravel";
}
function inferOutputType(workflow) {
if (workflow === "documentation-update" || workflow === "writing" || workflow === "editing" || workflow === "planning") {
return "documentation";
}
if (workflow === "project-question" || workflow === "research" || workflow === null) {
return "analysis";
}
if (workflow === "pentest" || workflow === "pentest-retest" || workflow === "root-cause-analysis") {
return "report";
}
return "code";
}
function inferCapabilityGap(targetCapability, profile) {
const activeCapabilities = new Set(
profile?.active_capabilities ?? (profile?.routing?.domain === "coding" ? ["content", "coding", "security"] : ["content"])
);
if (targetCapability === "content") {
return false;
}
if (targetCapability === "security") {
return !activeCapabilities.has("security");
}
return !activeCapabilities.has("coding");
}
function inferDatabaseImpact(request) {
if (request.includes("data migration")) {
return "data-migration";
}
if (request.includes("migration") || request.includes("schema") || request.includes("column") || request.includes("table")) {
return "schema-change";
}
if (request.includes("query") || request.includes("index")) {
return "query-change";
}
return "none";
}
function inferApiImpact(request) {
if (request.includes("breaking api") || request.includes("breaking endpoint")) {
return "breaking-change";
}
if (request.includes("api") || request.includes("endpoint") || request.includes("route")) {
return request.includes("modify") || request.includes("update") ? "modified-endpoint" : "additive-endpoint";
}
return "none";
}
function inferUiImpact(request) {
if (request.includes("redesign")) {
return "redesign";
}
if (request.includes("screen") || request.includes("dashboard") || request.includes("page")) {
return "new-screen";
}
if (request.includes("component") || request.includes("button") || request.includes("form")) {
return "new-component";
}
return "none";
}
function inferComplexity(request, workflow, databaseImpact, apiImpact, uiImpact, trivialSingleFile) {
if (trivialSingleFile || isTrivialRequest(request)) {
return "trivial";
}
if (workflow === "pentest" || workflow === "pentest-retest") {
return "high";
}
if (workflow === "documentation-update" || workflow === "root-cause-analysis") {
return "medium";
}
if (workflow === "project-question" || workflow === "research" || workflow === null) {
return "low";
}
if (databaseImpact === "schema-change" || databaseImpact === "data-migration" || apiImpact === "breaking-change" || uiImpact === "redesign") {
return "high";
}
if (apiImpact !== "none" || uiImpact !== "none") {
return "medium";
}
return "low";
}
function inferRisk(workflow, complexity, databaseImpact, apiImpact) {
if (workflow === "pentest" || workflow === "pentest-retest") {
return "high";
}
if (complexity === "high" || complexity === "very-high" || databaseImpact === "schema-change" || databaseImpact === "data-migration" || apiImpact === "breaking-change") {
return "high";
}
return complexity === "medium" ? "medium" : "low";
}
function inferScope(workflow, complexity, trivialSingleFile) {
if (trivialSingleFile || complexity === "trivial") {
return "single-file";
}
if (workflow === "documentation-update") {
return "system-wide";
}
if (complexity === "high" || complexity === "very-high") {
return "system-wide";
}
if (complexity === "medium") {
return "multi-module";
}
return "single-module";
}
function inferTrivialSingleFile(request) {
const normalized = request.toLowerCase();
const explicitPrefixes = extractExplicitModulePrefixes(request);
const singleExplicitFile = explicitPrefixes.length === 1 && /\.(tsx?|jsx?|vue|svelte|astro|php|dart|py|rb|go|rs|java|kt|cs|md)$/i.test(request);
if (singleExplicitFile && isTrivialRequest(normalized)) {
return true;
}
return isTrivialRequest(normalized) && mentionsAny(normalized, ["file", "rename", "cleanup", "comment", "typo", "one-line"]);
}
function isTrivialRequest(request) {
return mentionsAny(request, [
"rename",
"cleanup",
"clean up",
"typo",
"comment",
"one-line",
"one line",
"small",
"tiny",
"minor"
]);
}
function inferModules(request, stack) {
const explicitPrefixes = extractExplicitModulePrefixes(request);
if (explicitPrefixes.length > 0) {
return explicitPrefixes;
}
return inferStackAwareModulePrefixes(request.toLowerCase(), stack);
}
function extractExplicitModulePrefixes(request) {
const matches = request.match(
/\b(?:src|app|resources|database|routes|lib|tests|docs|packages)\/[A-Za-z0-9_./-]+\b/g
) ?? [];
return Array.from(
new Set(
matches.map(
(match) => stripTrailingChars(
match.replace(/\\/g, "/").replace(/\.(tsx?|jsx?|vue|svelte|astro|php|dart|py|rb|go|rs|java|kt|cs|md)$/i, ""),
"/"
)
)
)
).slice(0, 3);
}
function inferStackAwareModulePrefixes(request, stack) {
const prefixes = [];
if (mentionsAny(request, ["migration", "schema", "table", "column"])) {
prefixes.push("database/migrations");
}
if (mentionsAny(request, ["api", "endpoint", "route", "controller"])) {
prefixes.push(...apiModulePrefixesForStack(stack));
}
if (mentionsAny(request, ["dashboard", "page", "screen", "view"])) {
prefixes.push(...screenModulePrefixesForStack(stack));
}
if (mentionsAny(request, ["component", "button", "form", "widget"])) {
prefixes.push(...componentModulePrefixesForStack(stack));
}
return Array.from(new Set(prefixes)).slice(0, 3);
}
function mentionsAny(request, tokens) {
return tokens.some((token) => request.includes(token));
}
function apiModulePrefixesForStack(stack) {
switch (stack) {
case "laravel":
return ["app/Http/Controllers", "routes"];
case "django":
case "fastapi":
return ["app/api", "app/routes"];
case "flutter":
return ["lib/services"];
default:
return ["src/api", "src/server"];
}
}
function screenModulePrefixesForStack(stack) {
switch (stack) {
case "laravel":
return ["resources/views", "resources/js/pages"];
case "flutter":
return ["lib/screens"];
default:
return ["src/pages", "src/screens"];
}
}
function componentModulePrefixesForStack(stack) {
switch (stack) {
case "laravel":
return ["resources/js/components", "app/View/Components"];
case "flutter":
return ["lib/widgets"];
default:
return ["src/components"];
}
}
// src/pipeline/router.ts
init_esm_shims();
var DOCUMENTATION_PHASES = [
"request-classification",
"docs-first-load",
"analysis",
"documentation-update"
];
var PROJECT_QUESTION_PHASES = [
"request-classification",
"docs-first-load",
"analysis",
"question-answering"
];
var RCA_PHASES = [
"request-classification",
"docs-first-load",
"analysis",
"root-cause-analysis",
"documentation-update"
];
var PENTEST_PHASES = [
"request-classification",
"docs-first-load",
"analysis",
"pentest"
];
var PENTEST_RETEST_PHASES = [
"request-classification",
"docs-first-load",
"analysis",
"pentest-retest"
];
var CONTENT_RESEARCH_PHASES = [
"request-classification",
"docs-first-load",
"analysis",
"question-answering"
];
var LANE_PHASES = {
full: [
"request-classification",
"docs-first-load",
"analysis",
"sequence-planning",
"specification",
"user-flow",
"spec-review",
"implementation",
"implementation-review",
"verification-gates",
"documentation-update"
],
graduated: [
"request-classification",
"docs-first-load",
"analysis",
"sequence-planning",
"specification",
"spec-review",
"implementation",
"implementation-review",
"verification-gates",
"documentation-update"
],
fast: [
"request-classification",
"docs-first-load",
"implementation",
"implementation-review",
"verification-gates",
"documentation-update"
]
};
var PipelineRouter = class {
route(classification) {
if (classification.workflow === null) {
return {
lane: null,
phases: [],
route_reason: classification.workflow_reason ?? "No workflow matched the request."
};
}
const lane = classification.resume_lane ?? selectLaneFromClassification(classification);
if (!classification.resume_lane && classification.capability_gap && classification.target_capability !== "content" && classification.complexity !== "high" && classification.complexity !== "very-high" && classification.risk !== "high") {
return {
lane: "fast",
phases: [...PROJECT_QUESTION_PHASES]
};
}
if (classification.workflow === "module-documentation") {
return {
lane,
phases: [
"request-classification",
"docs-first-load",
"analysis",
"module-documentation"
]
};
}
if (classification.workflow === "documentation-update" || classification.workflow === "writing" || classification.workflow === "editing" || classification.workflow === "planning" || classification.output_type === "documentation") {
return {
lane,
phases: [...DOCUMENTATION_PHASES]
};
}
if (classification.workflow === "research") {
return {
lane: "fast",
phases: [...CONTENT_RESEARCH_PHASES]
};
}
if (classification.workflow === "project-question") {
return {
lane,
phases: [...PROJECT_QUESTION_PHASES]
};
}
if (classification.workflow === "root-cause-analysis") {
return {
lane,
phases: [...RCA_PHASES]
};
}
if (classification.workflow === "pentest") {
return {
lane,
phases: [...PENTEST_PHASES]
};
}
if (classification.workflow === "pentest-retest") {
return {
lane,
phases: [...PENTEST_RETEST_PHASES]
};
}
if (classification.workflow === "custom") {
return {
lane,
phases: [...LANE_PHASES[lane]]
};
}
return {
lane,
phases: [...LANE_PHASES[lane]],
route_reason: classification.workflow_continuity_reason ?? null
};
}
};
function selectLaneFromClassification(classification) {
if (classification.workflow === "project-question") {
return "fast";
}
if (classification.workflow === "writing" || classification.workflow === "editing" || classification.workflow === "planning" || classification.workflow === "research") {
return "fast";
}
if (classification.workflow === "custom") {
if (classification.complexity === "trivial" || classification.complexity === "low") {
return "fast";
}
return classification.risk === "high" ? "full" : "graduated";
}
if (classification.workflow === "investigation") {
return "fast";
}
if (classification.workflow === "pentest" || classification.workflow === "pentest-retest") {
return "graduated";
}
if (classification.workflow === "migration") {
return "full";
}
if (classification.workflow === "bug-fix") {
return classification.complexity === "low" && classification.risk === "low" ? "fast" : "graduated";
}
if (classification.workflow === "feature-development") {
return classification.risk === "high" ? "full" : "graduated";
}
if (classification.complexity === "trivial") {
return "fast";
}
if (classification.complexity === "low" && classification.risk === "low") {
return "fast";
}
if (classification.complexity === "low" && classification.risk !== "low") {
return "graduated";
}
if (classification.complexity === "medium" && classification.risk !== "high") {
return "graduated";
}
return "full";
}
export {
DEFECT_PATTERN_SCHEMA_VERSION,
defaultStoreRoot,
recordFindings,
queryPatterns,
prunePatterns,
loadIndex,
loadEntry,
ensureStoreDir,
markStaleEntries,
PLANNING_MANIFEST_VERSION,
PLAN_MODES,
PLANNING_LANES,
REQUIREMENT_TYPES,
PROOF_TYPES,
CRITERION_STATUSES,
HEALTH_TIERS,
ROLLBACK_CLASSES,
deriveHealthTier,
readModuleHealth,
writeModuleHealth,
writeModuleHealthProfile,
readAllModuleHealth,
initializeModuleHealth,
moduleHealthPath,
syncModuleHealth,
gatesThatPassed,
syncModuleHealthFromVerification,
createEvidence,
persistEvidence,
toProjectRelative,
loadManifest,
saveManifest,
manifestExists,
listManifestSlugs,
computeManifestHash,
computeClassificationConfidence,
PostClassifier,
estimateContextBudgetHint,
detectDeltaCandidate,
resolveImpacts,
ModuleResolver,
resolveScope,
toProjectRelativeModule,
PreClassifier,
isQuestionRoute,
hasCodeNegation,
isCreateArtifactAsk,
isAboutWorkPrompt,
shouldSkipLlm,
RequestClassifier,
LANE_PHASES,
PipelineRouter
};