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.
- package/README.md +163 -20
- package/dist/{canonical-CglQQ0xc.d.ts → canonical-JS6HUWGc.d.ts} +24 -1
- package/dist/cli/index.js +1433 -200
- package/dist/cli/index.js.map +1 -1
- package/dist/core/index.d.ts +52 -5
- package/dist/core/index.js +623 -1
- package/dist/core/index.js.map +1 -1
- package/dist/{filesystem-B3qAej0l.d.ts → filesystem-CrAkhr85.d.ts} +1 -1
- package/dist/index.d.ts +15 -9
- package/dist/index.js +1451 -303
- package/dist/index.js.map +1 -1
- package/dist/install/index.d.ts +59 -3
- package/dist/install/index.js +1245 -111
- package/dist/install/index.js.map +1 -1
- package/dist/jev/index.d.ts +1 -1
- package/dist/mcp/index.d.ts +12 -1
- package/dist/mcp/index.js +846 -97
- package/dist/mcp/index.js.map +1 -1
- package/dist/rules/index.d.ts +2 -2
- package/dist/rules/index.js.map +1 -1
- package/dist/scanner/index.d.ts +2 -2
- package/dist/scanner/index.js +6 -1
- package/dist/scanner/index.js.map +1 -1
- package/dist/search/index.d.ts +1 -1
- package/dist/stats/index.d.ts +3 -3
- package/dist/stats/index.js +45 -1
- package/dist/stats/index.js.map +1 -1
- package/dist/storage/index.d.ts +3 -3
- package/dist/storage/index.js +6 -1
- package/dist/storage/index.js.map +1 -1
- package/dist/{types-Nxq5Gzay.d.ts → types-DNlvHsj9.d.ts} +120 -3
- package/package.json +1 -1
package/dist/core/index.js
CHANGED
|
@@ -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
|