bilmem 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -316,7 +316,7 @@ function createKnowledge(params) {
316
316
  type: params.type ?? "lesson",
317
317
  status,
318
318
  stage: initialStage,
319
- statement: params.statement.trim(),
319
+ statement: (params.statement ?? params.question ?? params.id).trim(),
320
320
  positive: Array.from(new Set(params.positive?.map((p) => p.trim().toLowerCase()) ?? [])),
321
321
  negative: Array.from(new Set(params.negative?.map((n) => n.trim().toLowerCase()) ?? [])),
322
322
  relations: Array.from(new Set(params.relations?.map((r) => r.trim()) ?? [])),
@@ -346,6 +346,11 @@ function createKnowledge(params) {
346
346
  },
347
347
  history,
348
348
  value: 0,
349
+ lesson: params.lesson,
350
+ failure_details: params.failure_details,
351
+ context: params.context,
352
+ contradicts: params.contradicts ? Array.from(new Set(params.contradicts)) : void 0,
353
+ blocking: params.blocking,
349
354
  createdAt: now,
350
355
  updatedAt: now
351
356
  };
@@ -1599,6 +1604,7 @@ var Retriever = class {
1599
1604
  // src/core/resolver.ts
1600
1605
  var RELATIVE_COSTS = {
1601
1606
  USE_KNOWLEDGE: 1,
1607
+ REVALIDATE: 2,
1602
1608
  INSPECT_TEST: 2,
1603
1609
  INSPECT_FILE: 2,
1604
1610
  INSPECT_SYMBOL: 2.5,
@@ -1938,6 +1944,616 @@ async function resolveEpistemicQuery(options, storage, retriever) {
1938
1944
  receiptId
1939
1945
  };
1940
1946
  }
1947
+
1948
+ // src/core/preflight.ts
1949
+ import { execFile } from "child_process";
1950
+ import { promisify } from "util";
1951
+ import * as path from "path";
1952
+ import * as fs from "fs/promises";
1953
+ import YAML from "yaml";
1954
+ var execFileAsync = promisify(execFile);
1955
+ var STOP_WORDS = /* @__PURE__ */ new Set([
1956
+ "add",
1957
+ "implement",
1958
+ "create",
1959
+ "support",
1960
+ "with",
1961
+ "the",
1962
+ "a",
1963
+ "an",
1964
+ "for",
1965
+ "in",
1966
+ "to",
1967
+ "and",
1968
+ "of",
1969
+ "on",
1970
+ "from",
1971
+ "using",
1972
+ "via",
1973
+ "into",
1974
+ "by",
1975
+ "our",
1976
+ "new",
1977
+ "use",
1978
+ "make",
1979
+ "allow",
1980
+ "enable",
1981
+ "provide",
1982
+ "setup",
1983
+ "set"
1984
+ ]);
1985
+ var DOMAIN_KEYWORDS = {
1986
+ authentication: ["auth", "oauth", "login", "logout", "session", "jwt", "token", "credential", "sso", "password"],
1987
+ session: ["session", "cookie", "cookies", "expiry", "refresh", "token"],
1988
+ "user-identity": ["user", "account", "profile", "identity", "member", "role", "permission"],
1989
+ database: ["db", "database", "sql", "postgres", "sqlite", "migration", "schema", "table", "query"],
1990
+ storage: ["storage", "s3", "bucket", "file", "upload", "disk", "blob"],
1991
+ api: ["api", "endpoint", "http", "rest", "route", "controller", "middleware", "graphql"],
1992
+ caching: ["cache", "redis", "memcached", "ttl", "invalidation"],
1993
+ billing: ["payment", "stripe", "checkout", "billing", "subscription", "invoice", "credit"],
1994
+ "data-processing": ["import", "export", "csv", "bulk", "batch", "stream", "pipeline"]
1995
+ };
1996
+ function tokenizeGoal(goal) {
1997
+ return goal.toLowerCase().replace(/[^a-z0-9_-]/g, " ").split(/\s+/).filter((t) => t.length > 2 && !STOP_WORDS.has(t));
1998
+ }
1999
+ function inferLikelyDomains(tokens, knowledgeTags) {
2000
+ const domains = /* @__PURE__ */ new Set();
2001
+ for (const token of tokens) {
2002
+ for (const [domain, keywords] of Object.entries(DOMAIN_KEYWORDS)) {
2003
+ if (keywords.includes(token) || token.includes(domain)) {
2004
+ domains.add(domain);
2005
+ }
2006
+ }
2007
+ }
2008
+ for (const tag of knowledgeTags) {
2009
+ const norm = tag.toLowerCase().trim();
2010
+ if (DOMAIN_KEYWORDS[norm]) {
2011
+ domains.add(norm);
2012
+ }
2013
+ }
2014
+ return Array.from(domains);
2015
+ }
2016
+ function classifyUnknown(unknown, goalTokens, domainCues) {
2017
+ const text = `${unknown.id} ${unknown.statement || ""} ${unknown.question || unknown.next?.question || ""}`.toLowerCase();
2018
+ if (unknown.blocking === true) {
2019
+ const isDecision2 = /\b(should|whether|how to handle|what happens when|policy|strategy|linking|collision|merge|choice)\b/i.test(text);
2020
+ return {
2021
+ classification: "BLOCKING",
2022
+ isDecision: isDecision2 || true,
2023
+ reason: unknown.reason || "Blocking unknown identified for this goal"
2024
+ };
2025
+ }
2026
+ if (unknown.blocking === false) {
2027
+ const isDecision2 = /\b(should|whether|how to handle|what happens when|policy|strategy|choice)\b/i.test(text);
2028
+ return {
2029
+ classification: "NON_BLOCKING",
2030
+ isDecision: isDecision2,
2031
+ reason: "Operational or instrumentation detail not blocking core functionality"
2032
+ };
2033
+ }
2034
+ const isNonBlocking = /\b(analytics|telemetry|metric|event name|logging level|log format|button color|styling|theme)\b/i.test(text);
2035
+ if (isNonBlocking) {
2036
+ return {
2037
+ classification: "NON_BLOCKING",
2038
+ isDecision: /\b(should|which name|choice)\b/i.test(text),
2039
+ reason: "Operational or instrumentation detail not blocking core functionality"
2040
+ };
2041
+ }
2042
+ const isDecision = /\b(should|whether|how to handle|what happens when|policy|strategy|linking|collision|merge)\b/i.test(text);
2043
+ const isBlockingCandidate = /\b(link|linking|collision|duplicate|merge|security|permission|storage-engine|protocol|auth-flow|credentials)\b/i.test(text);
2044
+ const overlapsGoal = goalTokens.some((t) => text.includes(t)) || domainCues.some((d) => text.includes(d));
2045
+ if (isBlockingCandidate && (overlapsGoal || unknown.reason === "UNRESOLVABLE_LOCALLY")) {
2046
+ return {
2047
+ classification: "BLOCKING",
2048
+ isDecision: true,
2049
+ reason: "Unresolved architectural or behavioral decision critical to goal implementation"
2050
+ };
2051
+ }
2052
+ return {
2053
+ classification: "IMPORTANT",
2054
+ isDecision,
2055
+ reason: isDecision ? "Product or behavior decision requiring attention" : "Important implementation detail"
2056
+ };
2057
+ }
2058
+ function prioritizeQuestions(rawQuestions, blockingUnknowns) {
2059
+ const consolidated = /* @__PURE__ */ new Map();
2060
+ for (const rq of rawQuestions) {
2061
+ const qText = rq.question.trim();
2062
+ if (!qText) continue;
2063
+ const topic = rq.targetTopic || qText.toLowerCase().replace(/[^a-z0-9]/g, " ").slice(0, 30);
2064
+ let expectedResolutionValue = 1;
2065
+ if (rq.isBlocking) expectedResolutionValue += 2;
2066
+ if (rq.outcomeScore && rq.outcomeScore > 0) expectedResolutionValue += 1;
2067
+ if (rq.outcomeScore && rq.outcomeScore < 0) expectedResolutionValue -= 0.5;
2068
+ const interactionCost = 1;
2069
+ const priorityScore = Math.max(0.1, expectedResolutionValue) / interactionCost;
2070
+ const existing = consolidated.get(topic);
2071
+ if (!existing || priorityScore > (existing.priorityScore ?? 0)) {
2072
+ consolidated.set(topic, {
2073
+ question: qText,
2074
+ reason: rq.reason,
2075
+ targetTopic: rq.targetTopic,
2076
+ expectedResolutionValue,
2077
+ interactionCost,
2078
+ priorityScore
2079
+ });
2080
+ }
2081
+ }
2082
+ return Array.from(consolidated.values()).sort((a, b) => (b.priorityScore ?? 0) - (a.priorityScore ?? 0));
2083
+ }
2084
+ async function executePreflight(options, storage, retriever, index) {
2085
+ const goal = options.goal.trim();
2086
+ const explicitPositive = (options.positive ?? []).map((p) => p.trim().toLowerCase());
2087
+ const negative = (options.negative ?? []).map((n) => n.trim().toLowerCase());
2088
+ const scope = options.scope ?? "project";
2089
+ const goalTokens = tokenizeGoal(goal);
2090
+ const allKnowledge = await storage.getAllKnowledge();
2091
+ const allTags = allKnowledge.flatMap((k) => k.tags ?? []);
2092
+ const likelyDomains = inferLikelyDomains(goalTokens, allTags);
2093
+ const contextualPositive = Array.from(/* @__PURE__ */ new Set([...explicitPositive, ...likelyDomains, ...goalTokens]));
2094
+ let candidatePool = [];
2095
+ if (retriever) {
2096
+ const jevCandidates = await retriever.lookup({
2097
+ query: goal,
2098
+ positive: contextualPositive,
2099
+ negative,
2100
+ scope,
2101
+ limit: options.maxCandidates ?? 25,
2102
+ includeRejected: true
2103
+ });
2104
+ for (const r of jevCandidates) {
2105
+ if (r.knowledge) candidatePool.push(r.knowledge);
2106
+ }
2107
+ }
2108
+ if (candidatePool.length === 0) {
2109
+ candidatePool = allKnowledge.filter((k) => k.status !== "invalid" && k.status !== "superseded");
2110
+ } else {
2111
+ for (const k of allKnowledge) {
2112
+ if (!candidatePool.some((c) => c.id === k.id) && k.status !== "invalid" && k.status !== "superseded") {
2113
+ const matchesToken = goalTokens.some((t) => k.id.toLowerCase().includes(t) || k.statement.toLowerCase().includes(t));
2114
+ const matchesCues = k.positive.some((p) => contextualPositive.includes(p));
2115
+ if (matchesToken || matchesCues) {
2116
+ candidatePool.push(k);
2117
+ }
2118
+ }
2119
+ }
2120
+ }
2121
+ const jevResults = rerankCandidates(candidatePool, {
2122
+ query: goal,
2123
+ positive: contextualPositive,
2124
+ negative,
2125
+ scope
2126
+ });
2127
+ const matchingItems = [];
2128
+ const rejectedItems = [];
2129
+ for (const res of jevResults) {
2130
+ if (res.status === "REJECT") {
2131
+ const reason = res.explanation.negativeConflicts.length > 0 ? `Inapplicable: ${res.explanation.negativeConflicts.join(", ")} conflicts with current context` : res.explanation.reasons[0] || "Context mismatch";
2132
+ rejectedItems.push({ id: res.knowledge.id, reason });
2133
+ } else {
2134
+ matchingItems.push(res.knowledge);
2135
+ }
2136
+ }
2137
+ if (options.deep) {
2138
+ try {
2139
+ const { stdout: diffOutput } = await execFileAsync(
2140
+ "git",
2141
+ ["diff", "--name-only", "HEAD~1"],
2142
+ { cwd: storage.getBaseDir() ? path.dirname(storage.getBaseDir()) : process.cwd() }
2143
+ );
2144
+ const changedFiles = diffOutput.split("\n").map((f) => f.trim()).filter(Boolean);
2145
+ if (changedFiles.length > 0) {
2146
+ const staleness = checkKnowledgeListStaleness(matchingItems, changedFiles);
2147
+ for (const affected of staleness.affectedKnowledge) {
2148
+ const matchIdx = matchingItems.findIndex((m) => m.id === affected.id);
2149
+ if (matchIdx >= 0) {
2150
+ matchingItems[matchIdx] = affected;
2151
+ }
2152
+ }
2153
+ }
2154
+ } catch {
2155
+ }
2156
+ }
2157
+ const constraints = [];
2158
+ const lessons = [];
2159
+ const pastFailures = [];
2160
+ const stale = [];
2161
+ const known = [];
2162
+ let conflictedCount = 0;
2163
+ const CONSTRAINT_PATTERN = /\b(must|must not|never|only|cannot|require|required|boundary|strictly|prohibited|forbidden)\b/i;
2164
+ const FAILURE_PATTERN = /(fail|bug|error|crash|duplicate write|race condition|pressure|leak|revert|timeout)/i;
2165
+ const rootDir = storage.getBaseDir() ? path.dirname(storage.getBaseDir()) : process.cwd();
2166
+ for (const k of matchingItems) {
2167
+ const matchesContradiction = k.status === "contradicted" || k.contradicts && k.contradicts.some((cid) => matchingItems.some((m) => m.id === cid));
2168
+ if (matchesContradiction) {
2169
+ conflictedCount++;
2170
+ }
2171
+ let isStale = k.status === "needs_revalidation" || k.status === "stale";
2172
+ let staleReason = k.history?.[k.history.length - 1]?.reason || "Supporting source changed after last validation";
2173
+ const changedDeps = [];
2174
+ const candidateDeps = [...k.depends_on ?? [], ...k.evidence ?? []];
2175
+ const timestampStr = k.updated_at ?? k.updatedAt ?? k.createdAt;
2176
+ const knowledgeTime = new Date(timestampStr).getTime();
2177
+ for (const dep of candidateDeps) {
2178
+ const cleanPath = dep.replace(/^(file|code|test|doc):/, "").trim();
2179
+ if (!cleanPath) continue;
2180
+ const absPath = path.isAbsolute(cleanPath) ? cleanPath : path.resolve(rootDir, cleanPath);
2181
+ try {
2182
+ const stat2 = await fs.stat(absPath);
2183
+ if (stat2.mtimeMs > knowledgeTime + 500) {
2184
+ isStale = true;
2185
+ changedDeps.push(cleanPath);
2186
+ staleReason = `Supporting source changed after last validation (${cleanPath})`;
2187
+ }
2188
+ } catch {
2189
+ }
2190
+ }
2191
+ if (isStale) {
2192
+ stale.push({
2193
+ id: k.id,
2194
+ statement: k.statement,
2195
+ reason: staleReason,
2196
+ changedSources: changedDeps.length > 0 ? changedDeps : k.depends_on
2197
+ });
2198
+ continue;
2199
+ }
2200
+ const isConstraint = k.type === "rule" || k.type === "decision" || k.type === "convention" || CONSTRAINT_PATTERN.test(k.statement);
2201
+ if (isConstraint) {
2202
+ constraints.push({
2203
+ id: k.id,
2204
+ statement: k.statement,
2205
+ type: k.type,
2206
+ confidence: k.confidence,
2207
+ confidenceTier: k.confidenceTier,
2208
+ source: k.evidence?.[0]
2209
+ });
2210
+ continue;
2211
+ }
2212
+ const isFailure = k.type === "failure" || k.statement.startsWith("[FAILURE]") || k.statement.startsWith("[REVERT]") || FAILURE_PATTERN.test(k.statement) || k.metrics.failed_outcomes > 0;
2213
+ if (isFailure) {
2214
+ pastFailures.push({
2215
+ id: k.id,
2216
+ statement: k.statement,
2217
+ context: k.context || {
2218
+ positive: k.positive,
2219
+ negative: k.negative
2220
+ },
2221
+ failure: k.statement,
2222
+ lesson: k.lesson || k.reasoning || k.resolves?.[0],
2223
+ evidence: k.evidence
2224
+ });
2225
+ continue;
2226
+ }
2227
+ const isLesson = k.type === "lesson" && (k.id.includes("lesson") || k.tags?.includes("lesson") || k.statement.toLowerCase().includes("lesson")) || k.statement.toLowerCase().startsWith("lesson:") || k.statement.toLowerCase().includes("lesson:");
2228
+ if (isLesson) {
2229
+ lessons.push({
2230
+ id: k.id,
2231
+ statement: k.statement,
2232
+ confidence: k.confidence,
2233
+ domain: k.tags?.[0],
2234
+ evidence: k.evidence
2235
+ });
2236
+ continue;
2237
+ }
2238
+ if (k.status === "active" || k.stage === "active" || k.stage === "probation" || !k.status) {
2239
+ known.push({
2240
+ id: k.id,
2241
+ statement: k.statement,
2242
+ confidence: k.confidence,
2243
+ confidenceTier: k.confidenceTier,
2244
+ stage: k.stage
2245
+ });
2246
+ }
2247
+ }
2248
+ const unknownsFromStorage = await storage.getAllUnknowns();
2249
+ const unknownKnowledge = allKnowledge.filter((k) => k.type === "unknown");
2250
+ const unifiedUnknowns = [];
2251
+ const seenUnknownIds = /* @__PURE__ */ new Set();
2252
+ for (const u of unknownsFromStorage) {
2253
+ seenUnknownIds.add(u.id);
2254
+ unifiedUnknowns.push({
2255
+ id: u.id,
2256
+ statement: u.statement || u.id,
2257
+ reason: u.reason,
2258
+ question: u.question || u.next?.question,
2259
+ next: u.next,
2260
+ blocking: u.blocking,
2261
+ positive: u.positive,
2262
+ negative: u.negative,
2263
+ checked: u.checked
2264
+ });
2265
+ }
2266
+ for (const k of unknownKnowledge) {
2267
+ if (!seenUnknownIds.has(k.id)) {
2268
+ seenUnknownIds.add(k.id);
2269
+ unifiedUnknowns.push({
2270
+ id: k.id,
2271
+ statement: k.statement,
2272
+ reason: k.history?.[0]?.reason,
2273
+ question: k.question || (k.statement.includes("?") ? k.statement : void 0),
2274
+ next: {
2275
+ type: "ask",
2276
+ target: k.id,
2277
+ question: k.question || k.statement
2278
+ },
2279
+ blocking: k.blocking,
2280
+ positive: k.positive,
2281
+ negative: k.negative,
2282
+ checked: k.depends_on || k.evidence
2283
+ });
2284
+ }
2285
+ }
2286
+ const unknowns = [];
2287
+ const missing = [];
2288
+ const rawQuestions = [];
2289
+ for (const u of unifiedUnknowns) {
2290
+ const text = `${u.id} ${u.statement || ""} ${u.question || ""}`.toLowerCase();
2291
+ const overlaps = goalTokens.some((t) => text.includes(t)) || likelyDomains.some((d) => text.includes(d)) || u.positive && u.positive.some((p) => contextualPositive.includes(p));
2292
+ if (u.negative && u.negative.some((n) => contextualPositive.includes(n))) {
2293
+ continue;
2294
+ }
2295
+ if (overlaps) {
2296
+ const { classification, isDecision, reason } = classifyUnknown(u, goalTokens, likelyDomains);
2297
+ const isBlocking = classification === "BLOCKING";
2298
+ unknowns.push({
2299
+ id: u.id,
2300
+ statement: u.statement,
2301
+ question: u.question || u.statement,
2302
+ classification,
2303
+ blocking: isBlocking,
2304
+ reason
2305
+ });
2306
+ if (isDecision) {
2307
+ missing.push({
2308
+ type: "decision",
2309
+ subject: u.id,
2310
+ question: u.question || u.statement,
2311
+ reason
2312
+ });
2313
+ } else {
2314
+ missing.push({
2315
+ type: "evidence",
2316
+ subject: u.id,
2317
+ question: u.question || u.statement,
2318
+ reason
2319
+ });
2320
+ }
2321
+ const qText = u.question || (u.statement && u.statement.includes("?") ? u.statement : void 0);
2322
+ if (qText) {
2323
+ rawQuestions.push({
2324
+ question: qText,
2325
+ reason: `Unknown: ${u.id} (${reason})`,
2326
+ targetTopic: u.id,
2327
+ isBlocking
2328
+ });
2329
+ }
2330
+ }
2331
+ }
2332
+ const questionKnowledge = allKnowledge.filter((k) => k.type === "question");
2333
+ for (const qk of questionKnowledge) {
2334
+ const matchesCues = qk.positive.some((p) => contextualPositive.includes(p));
2335
+ const conflicts = qk.negative.some((n) => negative.includes(n));
2336
+ if (matchesCues && !conflicts && qk.question) {
2337
+ rawQuestions.push({
2338
+ question: qk.question,
2339
+ reason: `Learned question for [${qk.positive.join(", ")}] uncertainty`,
2340
+ targetTopic: qk.resolves?.[0] || qk.id,
2341
+ outcomeScore: (qk.metrics?.successful_outcomes ?? 0) - (qk.metrics?.failed_outcomes ?? 0)
2342
+ });
2343
+ }
2344
+ }
2345
+ const questions = prioritizeQuestions(rawQuestions, unknowns);
2346
+ const receipts = await storage.getAllReceipts();
2347
+ const alreadyInvestigated = [];
2348
+ const investigatedSources = /* @__PURE__ */ new Set();
2349
+ for (const r of receipts) {
2350
+ const qTokens = r.question.toLowerCase().split(/\s+/).filter(Boolean);
2351
+ const overlapsGoal = qTokens.some((t) => goalTokens.includes(t));
2352
+ const overlapsCues = r.positive && r.positive.some((p) => contextualPositive.includes(p));
2353
+ if (overlapsGoal || overlapsCues) {
2354
+ for (const checked of r.checked) {
2355
+ investigatedSources.add(checked.toLowerCase());
2356
+ alreadyInvestigated.push({
2357
+ source: checked,
2358
+ result: r.findings[0] || r.rejected[0]?.reason || "Did not establish requested behavior",
2359
+ nextSuggestion: "ASK_USER"
2360
+ });
2361
+ }
2362
+ }
2363
+ }
2364
+ let readiness = "READY";
2365
+ const totalRelevantKnowledge = known.length + constraints.length + lessons.length + pastFailures.length + stale.length;
2366
+ const hasBlockingUnknown = unknowns.some((u) => u.blocking);
2367
+ const hasMissingDecision = missing.some((m) => m.type === "decision");
2368
+ if (totalRelevantKnowledge === 0 && unknowns.length === 0) {
2369
+ readiness = "INSUFFICIENT_KNOWLEDGE";
2370
+ } else if (conflictedCount > 0) {
2371
+ readiness = "CONFLICTED";
2372
+ } else if (hasBlockingUnknown || hasMissingDecision) {
2373
+ readiness = "NEEDS_CLARIFICATION";
2374
+ } else if (stale.length > 0) {
2375
+ readiness = "NEEDS_REVALIDATION";
2376
+ } else {
2377
+ readiness = "READY";
2378
+ }
2379
+ const next = [];
2380
+ for (const m of missing) {
2381
+ if (m.type === "decision") {
2382
+ next.push({
2383
+ type: "ASK_USER",
2384
+ target: m.subject,
2385
+ reason: m.question || m.reason,
2386
+ relativeCost: 1,
2387
+ expectedInfoGain: 0.95
2388
+ });
2389
+ }
2390
+ }
2391
+ for (const s of stale) {
2392
+ next.push({
2393
+ type: "REVALIDATE",
2394
+ target: s.id,
2395
+ reason: s.reason,
2396
+ relativeCost: 2,
2397
+ expectedInfoGain: 0.85
2398
+ });
2399
+ }
2400
+ for (const m of missing) {
2401
+ if (m.type === "evidence") {
2402
+ const wasChecked = investigatedSources.has(m.subject.toLowerCase()) || alreadyInvestigated.length > 0;
2403
+ if (wasChecked) {
2404
+ if (!next.some((n) => n.type === "ASK_USER")) {
2405
+ next.push({
2406
+ type: "ASK_USER",
2407
+ target: m.subject,
2408
+ reason: `Already investigated (${Array.from(investigatedSources).join(", ")}); did not establish requested behavior. Clarification required.`,
2409
+ relativeCost: 1,
2410
+ expectedInfoGain: 0.9
2411
+ });
2412
+ }
2413
+ } else {
2414
+ const isFilePath = m.subject.includes("/") || m.subject.includes(".");
2415
+ next.push({
2416
+ type: isFilePath ? "INSPECT_FILE" : "SEARCH_REPOSITORY",
2417
+ target: m.subject,
2418
+ reason: m.reason,
2419
+ relativeCost: isFilePath ? 2 : 2.5,
2420
+ expectedInfoGain: 0.8
2421
+ });
2422
+ }
2423
+ }
2424
+ }
2425
+ if (alreadyInvestigated.length > 0 && !next.some((n) => n.type === "ASK_USER")) {
2426
+ next.push({
2427
+ type: "ASK_USER",
2428
+ target: alreadyInvestigated[0].source,
2429
+ reason: `Already investigated ${alreadyInvestigated[0].source}; clarification required`,
2430
+ relativeCost: 1,
2431
+ expectedInfoGain: 0.9
2432
+ });
2433
+ }
2434
+ if (next.length === 0 && known.length > 0) {
2435
+ next.push({
2436
+ type: "USE_KNOWLEDGE",
2437
+ target: known[0].id,
2438
+ reason: "Proceed with implementation using verified knowledge and constraints",
2439
+ relativeCost: 1,
2440
+ expectedInfoGain: 1
2441
+ });
2442
+ }
2443
+ const knowledgeImpact = {
2444
+ relevantKnowledge: totalRelevantKnowledge,
2445
+ validated: known.filter((k) => k.confidenceTier === "high").length + constraints.length,
2446
+ needsRevalidation: stale.length,
2447
+ conflicted: conflictedCount,
2448
+ blockingUnknowns: unknowns.filter((u) => u.blocking).length,
2449
+ relevantFailures: pastFailures.length
2450
+ };
2451
+ const similarWork = [];
2452
+ for (const l of lessons) {
2453
+ similarWork.push({
2454
+ topic: l.domain || l.id,
2455
+ lesson: l.statement
2456
+ });
2457
+ }
2458
+ for (const f of pastFailures) {
2459
+ similarWork.push({
2460
+ topic: f.id,
2461
+ failure: f.statement
2462
+ });
2463
+ }
2464
+ await storage.appendMetricEvent({
2465
+ type: "preflight",
2466
+ goal,
2467
+ readiness,
2468
+ blockingUnknownsCount: knowledgeImpact.blockingUnknowns,
2469
+ staleKnowledgeCount: stale.length,
2470
+ pastFailuresCount: pastFailures.length,
2471
+ questionsCount: questions.length,
2472
+ repeatedChecksAvoidedCount: alreadyInvestigated.length,
2473
+ timestamp: Date.now()
2474
+ });
2475
+ return {
2476
+ goal,
2477
+ readiness,
2478
+ known,
2479
+ constraints,
2480
+ lessons,
2481
+ past_failures: pastFailures,
2482
+ unknowns,
2483
+ stale,
2484
+ missing,
2485
+ questions,
2486
+ likely_domains: likelyDomains,
2487
+ similar_work: similarWork.length > 0 ? similarWork.slice(0, 5) : void 0,
2488
+ already_investigated: alreadyInvestigated.length > 0 ? alreadyInvestigated : void 0,
2489
+ knowledge_impact: knowledgeImpact,
2490
+ next
2491
+ };
2492
+ }
2493
+ function formatPreflightReport(result) {
2494
+ const plainObject = {
2495
+ goal: result.goal,
2496
+ readiness: result.readiness
2497
+ };
2498
+ if (result.known.length > 0) {
2499
+ plainObject.known = result.known.map((k) => ({
2500
+ id: k.id,
2501
+ statement: k.statement,
2502
+ confidence: k.confidenceTier || (typeof k.confidence === "number" ? k.confidence >= 0.9 ? "high" : k.confidence >= 0.7 ? "medium" : "low" : k.confidence)
2503
+ }));
2504
+ }
2505
+ if (result.constraints.length > 0) {
2506
+ plainObject.constraints = result.constraints.map((c) => ({
2507
+ id: c.id,
2508
+ statement: c.statement
2509
+ }));
2510
+ }
2511
+ if (result.lessons.length > 0) {
2512
+ plainObject.lessons = result.lessons.map((l) => ({
2513
+ id: l.id,
2514
+ statement: l.statement
2515
+ }));
2516
+ }
2517
+ if (result.past_failures.length > 0) {
2518
+ plainObject.past_failures = result.past_failures.map((f) => ({
2519
+ id: f.id,
2520
+ statement: f.statement
2521
+ }));
2522
+ }
2523
+ if (result.unknowns.length > 0) {
2524
+ plainObject.unknowns = result.unknowns.map((u) => ({
2525
+ id: u.id,
2526
+ question: u.question || u.statement,
2527
+ blocking: u.blocking
2528
+ }));
2529
+ }
2530
+ if (result.stale.length > 0) {
2531
+ plainObject.stale = result.stale.map((s) => ({
2532
+ id: s.id,
2533
+ reason: s.reason
2534
+ }));
2535
+ }
2536
+ if (result.questions.length > 0) {
2537
+ plainObject.questions = result.questions.map((q) => ({
2538
+ question: q.question,
2539
+ reason: q.reason
2540
+ }));
2541
+ }
2542
+ if (result.likely_domains.length > 0) {
2543
+ plainObject.likely_domains = result.likely_domains;
2544
+ }
2545
+ if (result.already_investigated && result.already_investigated.length > 0) {
2546
+ plainObject.already_investigated = result.already_investigated;
2547
+ }
2548
+ if (result.next.length > 0) {
2549
+ plainObject.next = result.next.map((n) => ({
2550
+ type: n.type,
2551
+ target: n.target,
2552
+ reason: n.reason
2553
+ }));
2554
+ }
2555
+ return YAML.stringify(plainObject);
2556
+ }
1941
2557
  export {
1942
2558
  EvidenceGraph,
1943
2559
  MetricsTracker,
@@ -1949,6 +2565,7 @@ export {
1949
2565
  calculateKnowledgeValue,
1950
2566
  checkKnowledgeListStaleness,
1951
2567
  checkKnowledgeStaleness,
2568
+ classifyUnknown,
1952
2569
  confidenceToTier,
1953
2570
  createEvidence,
1954
2571
  createKnowledge,
@@ -1960,16 +2577,21 @@ export {
1960
2577
  distillTrajectory,
1961
2578
  enforceKnowledgeBudget,
1962
2579
  evaluatePromotion,
2580
+ executePreflight,
2581
+ formatPreflightReport,
1963
2582
  hasBeenInvestigated,
1964
2583
  hashString,
2584
+ inferLikelyDomains,
1965
2585
  learnFromTrajectory,
1966
2586
  markStaleKnowledge,
1967
2587
  normalizeSourceKey,
2588
+ prioritizeQuestions,
1968
2589
  processUserCorrection,
1969
2590
  reconcileKnowledge,
1970
2591
  recordOutcomeOnKnowledge,
1971
2592
  resolveEpistemicQuery,
1972
2593
  tierToConfidence,
2594
+ tokenizeGoal,
1973
2595
  updateUnknown
1974
2596
  };
1975
2597
  //# sourceMappingURL=index.js.map