@lucern/graph-primitives 1.0.16 → 1.0.18
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/dist/beliefEvidenceLinks.js +144 -99
- package/dist/beliefEvidenceLinks.js.map +1 -1
- package/dist/beliefEvidenceLinks.operational.d.ts +29 -0
- package/dist/beliefEvidenceLinks.operational.js +157 -0
- package/dist/beliefEvidenceLinks.operational.js.map +1 -0
- package/dist/{beliefLifecycle-y8WLXqQj.d.ts → beliefLifecycle-CXwdDw5e.d.ts} +7 -4
- package/dist/beliefLifecycle.d.ts +1 -1
- package/dist/beliefLifecycle.js +75 -18
- package/dist/beliefLifecycle.js.map +1 -1
- package/dist/entityLifecycle.js +1 -12
- package/dist/entityLifecycle.js.map +1 -1
- package/dist/epistemicAnswers.js +1 -12
- package/dist/epistemicAnswers.js.map +1 -1
- package/dist/epistemicBeliefs.admin.js.map +1 -1
- package/dist/epistemicBeliefs.backfills.d.ts +1 -1
- package/dist/epistemicBeliefs.backfills.js +63 -35
- package/dist/epistemicBeliefs.backfills.js.map +1 -1
- package/dist/epistemicBeliefs.confidence.d.ts +1 -1
- package/dist/epistemicBeliefs.confidence.js +70 -41
- package/dist/epistemicBeliefs.confidence.js.map +1 -1
- package/dist/epistemicBeliefs.core.js +946 -566
- package/dist/epistemicBeliefs.core.js.map +1 -1
- package/dist/epistemicBeliefs.d.ts +2 -2
- package/dist/epistemicBeliefs.forkEvidence.d.ts +18 -0
- package/dist/epistemicBeliefs.forkEvidence.js +121 -0
- package/dist/epistemicBeliefs.forkEvidence.js.map +1 -0
- package/dist/epistemicBeliefs.helpers.d.ts +2 -2
- package/dist/epistemicBeliefs.helpers.js +60 -32
- package/dist/epistemicBeliefs.helpers.js.map +1 -1
- package/dist/epistemicBeliefs.internal.js +175 -51
- package/dist/epistemicBeliefs.internal.js.map +1 -1
- package/dist/epistemicBeliefs.js +437 -84
- package/dist/epistemicBeliefs.js.map +1 -1
- package/dist/epistemicBeliefs.lifecycle.d.ts +2 -2
- package/dist/epistemicBeliefs.lifecycle.js +75 -47
- package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
- package/dist/epistemicBeliefs.links.js +47 -13
- package/dist/epistemicBeliefs.links.js.map +1 -1
- package/dist/epistemicBeliefs.topicAnchor.d.ts +29 -0
- package/dist/epistemicBeliefs.topicAnchor.js +105 -0
- package/dist/epistemicBeliefs.topicAnchor.js.map +1 -0
- package/dist/epistemicContracts.evaluators.js +71 -42
- package/dist/epistemicContracts.evaluators.js.map +1 -1
- package/dist/epistemicContracts.handlers.js +72 -54
- package/dist/epistemicContracts.handlers.js.map +1 -1
- package/dist/epistemicContracts.js +72 -54
- package/dist/epistemicContracts.js.map +1 -1
- package/dist/epistemicContracts.metrics.js +1 -1
- package/dist/epistemicContracts.metrics.js.map +1 -1
- package/dist/epistemicContracts.types.d.ts +1 -1
- package/dist/epistemicEdgeCreation.js +1 -12
- package/dist/epistemicEdgeCreation.js.map +1 -1
- package/dist/epistemicEdges.helpers.d.ts +1 -1
- package/dist/epistemicEvidence.js +173 -93
- package/dist/epistemicEvidence.js.map +1 -1
- package/dist/epistemicEvidenceMutations.js +173 -93
- package/dist/epistemicEvidenceMutations.js.map +1 -1
- package/dist/epistemicHelpers.js +1 -12
- package/dist/epistemicHelpers.js.map +1 -1
- package/dist/epistemicNodeCreation.js +1 -10
- package/dist/epistemicNodeCreation.js.map +1 -1
- package/dist/epistemicNodes.internal.js.map +1 -1
- package/dist/epistemicNodes.js +2 -2
- package/dist/epistemicNodes.js.map +1 -1
- package/dist/epistemicNodes.mutations.js +2 -2
- package/dist/epistemicNodes.mutations.js.map +1 -1
- package/dist/epistemicQuestions.create.js +1 -12
- package/dist/epistemicQuestions.create.js.map +1 -1
- package/dist/epistemicQuestions.evidence.js +1 -12
- package/dist/epistemicQuestions.evidence.js.map +1 -1
- package/dist/epistemicQuestions.js +1 -12
- package/dist/epistemicQuestions.js.map +1 -1
- package/dist/epistemicQuestions.tail.js +1 -12
- package/dist/epistemicQuestions.tail.js.map +1 -1
- package/dist/epistemicSources.js +1 -12
- package/dist/epistemicSources.js.map +1 -1
- package/dist/evaluators/index.js +1 -1
- package/dist/evaluators/index.js.map +1 -1
- package/dist/globalId-4y9SPpC_.d.ts +10 -0
- package/dist/globalId.d.ts +1 -1
- package/dist/globalId.js +1 -13
- package/dist/globalId.js.map +1 -1
- package/dist/helpers.js +1 -12
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +771 -247
- package/dist/index.js.map +1 -1
- package/dist/invariantEnforcement.js +2 -2
- package/dist/invariantEnforcement.js.map +1 -1
- package/dist/proof-attestation.json +3 -3
- package/package.json +4 -4
- package/dist/globalId-DKh9d_uD.d.ts +0 -20
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { componentsGeneric, anyApi } from 'convex/server';
|
|
2
|
+
|
|
3
|
+
// src/convex.ts
|
|
4
|
+
componentsGeneric();
|
|
5
|
+
var internal = anyApi;
|
|
6
|
+
|
|
7
|
+
// src/epistemicBeliefs.topicAnchor.ts
|
|
8
|
+
function cleanString(value) {
|
|
9
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
10
|
+
}
|
|
11
|
+
function topicNodeCandidates(topicRef) {
|
|
12
|
+
const normalized = topicRef.trim();
|
|
13
|
+
if (!normalized) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const candidates = [normalized];
|
|
17
|
+
if (normalized.startsWith("top_")) {
|
|
18
|
+
candidates.push(normalized.slice(4));
|
|
19
|
+
}
|
|
20
|
+
return [...new Set(candidates)];
|
|
21
|
+
}
|
|
22
|
+
function readTopicNodeRef(args) {
|
|
23
|
+
return cleanString(args.topicGlobalId) ?? cleanString(args.topicNodeId) ?? cleanString(args.topicId);
|
|
24
|
+
}
|
|
25
|
+
async function resolveRequiredTopicAnchor(ctx, topicRef) {
|
|
26
|
+
for (const candidate of topicNodeCandidates(topicRef)) {
|
|
27
|
+
try {
|
|
28
|
+
const direct = await ctx.db.get(candidate);
|
|
29
|
+
if (direct?.nodeType === "topic" && cleanString(direct.globalId)) {
|
|
30
|
+
return direct;
|
|
31
|
+
}
|
|
32
|
+
} catch (_) {
|
|
33
|
+
}
|
|
34
|
+
const byGlobalId = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", candidate)).first();
|
|
35
|
+
if (byGlobalId?.nodeType === "topic" && cleanString(byGlobalId.globalId)) {
|
|
36
|
+
return byGlobalId;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
throw new Error(
|
|
40
|
+
"Belief creation requires topicGlobalId or topicNodeId for a topic node in epistemicNodes. Legacy topics-table IDs are not valid belief anchors."
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
function scopeFromTopicAnchor(topicNode) {
|
|
44
|
+
return {
|
|
45
|
+
topicId: topicNode.globalId,
|
|
46
|
+
projectId: cleanString(topicNode.projectId),
|
|
47
|
+
tenantId: cleanString(topicNode.tenantId),
|
|
48
|
+
workspaceId: cleanString(topicNode.workspaceId),
|
|
49
|
+
source: "topic"
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
async function createRequiredBeliefTopicEdge(ctx, args) {
|
|
53
|
+
const topicGlobalId = args.topicNode.globalId;
|
|
54
|
+
const edgeGlobalId = `edge:${args.beliefGlobalId}:${topicGlobalId}:scoped_by`;
|
|
55
|
+
const now = Date.now();
|
|
56
|
+
const existing = await ctx.db.query("epistemicEdges").withIndex("by_globalId", (q) => q.eq("globalId", edgeGlobalId)).first();
|
|
57
|
+
if (!existing) {
|
|
58
|
+
await ctx.db.insert("epistemicEdges", {
|
|
59
|
+
globalId: edgeGlobalId,
|
|
60
|
+
fromNodeId: String(args.beliefNodeId),
|
|
61
|
+
toNodeId: String(args.topicNode._id),
|
|
62
|
+
sourceGlobalId: args.beliefGlobalId,
|
|
63
|
+
targetGlobalId: topicGlobalId,
|
|
64
|
+
edgeType: "scoped_by",
|
|
65
|
+
weight: 1,
|
|
66
|
+
confidence: 1,
|
|
67
|
+
context: "Belief creation topic anchor invariant.",
|
|
68
|
+
reasoningMethod: "implicit",
|
|
69
|
+
derivationType: "topic_scope_invariant",
|
|
70
|
+
metadata: { invariant: "belief.topic_edge_required" },
|
|
71
|
+
createdBy: args.createdBy,
|
|
72
|
+
createdAt: now,
|
|
73
|
+
updatedAt: now,
|
|
74
|
+
projectId: cleanString(args.topicNode.projectId),
|
|
75
|
+
topicId: topicGlobalId,
|
|
76
|
+
tenantId: cleanString(args.topicNode.tenantId),
|
|
77
|
+
workspaceId: cleanString(args.topicNode.workspaceId),
|
|
78
|
+
fromNodeType: "belief",
|
|
79
|
+
toNodeType: "topic",
|
|
80
|
+
fromLayer: "L3",
|
|
81
|
+
toLayer: args.topicNode.epistemicLayer ?? "ontological"
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {
|
|
85
|
+
globalId: edgeGlobalId,
|
|
86
|
+
fromGlobalId: args.beliefGlobalId,
|
|
87
|
+
toGlobalId: topicGlobalId,
|
|
88
|
+
edgeType: "scoped_by",
|
|
89
|
+
weight: 1,
|
|
90
|
+
confidence: 1,
|
|
91
|
+
context: "Belief creation topic anchor invariant.",
|
|
92
|
+
projectId: cleanString(args.topicNode.projectId),
|
|
93
|
+
topicId: topicGlobalId,
|
|
94
|
+
createdBy: args.createdBy,
|
|
95
|
+
fromNodeType: "belief",
|
|
96
|
+
toNodeType: "topic",
|
|
97
|
+
fromLayer: "L3",
|
|
98
|
+
toLayer: args.topicNode.epistemicLayer ?? "ontological",
|
|
99
|
+
metadata: { invariant: "belief.topic_edge_required" }
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export { createRequiredBeliefTopicEdge, readTopicNodeRef, resolveRequiredTopicAnchor, scopeFromTopicAnchor };
|
|
104
|
+
//# sourceMappingURL=epistemicBeliefs.topicAnchor.js.map
|
|
105
|
+
//# sourceMappingURL=epistemicBeliefs.topicAnchor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/convex.ts","../src/epistemicBeliefs.topicAnchor.ts"],"names":[],"mappings":"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","file":"epistemicBeliefs.topicAnchor.js","sourcesContent":["import {\n actionGeneric,\n anyApi,\n componentsGeneric,\n httpActionGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n mutationGeneric,\n queryGeneric,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\nexport const api = anyApi as any;\nexport const components = componentsGeneric() as any;\nexport const internal = anyApi as any;\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> = any;\nexport type DataModel = any;\ntype IndexRangeBuilder = {\n field(fieldName: string): string;\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n gt(fieldName: string, value: unknown): IndexRangeBuilder;\n gte(fieldName: string, value: unknown): IndexRangeBuilder;\n lt(fieldName: string, value: unknown): IndexRangeBuilder;\n lte(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype FilterBuilder = {\n eq(left: unknown, right: unknown): unknown;\n neq(left: unknown, right: unknown): unknown;\n gt(left: unknown, right: unknown): unknown;\n gte(left: unknown, right: unknown): unknown;\n lt(left: unknown, right: unknown): unknown;\n lte(left: unknown, right: unknown): unknown;\n and(...clauses: unknown[]): unknown;\n or(...clauses: unknown[]): unknown;\n field(fieldName: string): unknown;\n};\ntype QueryInitializer<TableName extends TableNames> = {\n withIndex(\n indexName: string,\n range?: (q: any) => unknown\n ): QueryInitializer<TableName>;\n filter(predicate: (q: any) => unknown): QueryInitializer<TableName>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n collect(): Promise<Doc<TableName>[]>;\n take(limit: number): Promise<Doc<TableName>[]>;\n first(): Promise<Doc<TableName> | null>;\n unique(): Promise<Doc<TableName> | null>;\n};\nexport type DatabaseReader = {\n get<TableName extends TableNames>(\n id: Id<TableName>\n ): Promise<Doc<TableName> | null>;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n};\nexport type DatabaseWriter = DatabaseReader & {\n insert<TableName extends TableNames>(\n tableName: TableName,\n value: Record<string, unknown>\n ): Promise<Id<TableName>>;\n patch<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n replace<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n delete<TableName extends TableNames>(id: Id<TableName>): Promise<void>;\n};\ntype Scheduler = {\n runAfter(delayMs: number, functionReference: unknown, args?: unknown): Promise<void>;\n};\ntype AuthReader = {\n getUserIdentity(): Promise<unknown>;\n};\ntype RuntimeInvoker = {\n runQuery(functionReference: unknown, args?: unknown): Promise<any>;\n runMutation(functionReference: unknown, args?: unknown): Promise<any>;\n runAction(functionReference: unknown, args?: unknown): Promise<any>;\n};\nexport type QueryCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseReader;\n scheduler: Scheduler;\n};\nexport type MutationCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseWriter;\n scheduler: Scheduler;\n};\nexport type ActionCtx = RuntimeInvoker & {\n auth: AuthReader;\n scheduler: Scheduler;\n};\n\ntype ConvexFunctionBuilder<Ctx> = <\n Definition extends { handler?: (ctx: Ctx, args: any) => any },\n>(\n definition: Definition\n) => any;\n\nexport const action = actionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const httpAction =\n httpActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalAction =\n internalActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalMutation =\n internalMutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","import type { Doc, Id, MutationCtx } from \"./convex\";\nimport { internal } from \"./convex\";\n\ntype TopicAnchorInput = {\n topicId?: string;\n topicNodeId?: string;\n topicGlobalId?: string;\n};\n\ntype TopicNodeDoc = Doc<\"epistemicNodes\"> & {\n globalId: string;\n nodeType: \"topic\";\n};\n\nfunction cleanString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0\n ? value.trim()\n : undefined;\n}\n\nfunction topicNodeCandidates(topicRef: string): string[] {\n const normalized = topicRef.trim();\n if (!normalized) {\n return [];\n }\n const candidates = [normalized];\n if (normalized.startsWith(\"top_\")) {\n candidates.push(normalized.slice(4));\n }\n return [...new Set(candidates)];\n}\n\nexport function readTopicNodeRef(args: TopicAnchorInput): string | undefined {\n return (\n cleanString(args.topicGlobalId) ??\n cleanString(args.topicNodeId) ??\n cleanString(args.topicId)\n );\n}\n\nexport async function resolveRequiredTopicAnchor(\n ctx: MutationCtx,\n topicRef: string,\n): Promise<TopicNodeDoc> {\n for (const candidate of topicNodeCandidates(topicRef)) {\n try {\n const direct = await ctx.db.get(candidate as Id<\"epistemicNodes\">);\n if (direct?.nodeType === \"topic\" && cleanString(direct.globalId)) {\n return direct as TopicNodeDoc;\n }\n } catch (_) {\n // Not a component-local epistemicNodes _id; try the globalId index next.\n }\n\n const byGlobalId = await ctx.db\n .query(\"epistemicNodes\")\n .withIndex(\"by_globalId\", (q) => q.eq(\"globalId\", candidate))\n .first();\n if (byGlobalId?.nodeType === \"topic\" && cleanString(byGlobalId.globalId)) {\n return byGlobalId as TopicNodeDoc;\n }\n }\n\n throw new Error(\n \"Belief creation requires topicGlobalId or topicNodeId for a topic node in epistemicNodes. Legacy topics-table IDs are not valid belief anchors.\",\n );\n}\n\nexport function scopeFromTopicAnchor(topicNode: TopicNodeDoc) {\n return {\n topicId: topicNode.globalId,\n projectId: cleanString(topicNode.projectId),\n tenantId: cleanString(topicNode.tenantId),\n workspaceId: cleanString(topicNode.workspaceId),\n source: \"topic\" as const,\n };\n}\n\nexport async function createRequiredBeliefTopicEdge(\n ctx: MutationCtx,\n args: {\n beliefNodeId: Id<\"epistemicNodes\">;\n beliefGlobalId: string;\n topicNode: TopicNodeDoc;\n createdBy: string;\n },\n) {\n const topicGlobalId = args.topicNode.globalId;\n const edgeGlobalId = `edge:${args.beliefGlobalId}:${topicGlobalId}:scoped_by`;\n const now = Date.now();\n\n const existing = await ctx.db\n .query(\"epistemicEdges\")\n .withIndex(\"by_globalId\", (q) => q.eq(\"globalId\", edgeGlobalId))\n .first();\n if (!existing) {\n await ctx.db.insert(\"epistemicEdges\", {\n globalId: edgeGlobalId,\n fromNodeId: String(args.beliefNodeId),\n toNodeId: String(args.topicNode._id),\n sourceGlobalId: args.beliefGlobalId,\n targetGlobalId: topicGlobalId,\n edgeType: \"scoped_by\",\n weight: 1,\n confidence: 1,\n context: \"Belief creation topic anchor invariant.\",\n reasoningMethod: \"implicit\",\n derivationType: \"topic_scope_invariant\",\n metadata: { invariant: \"belief.topic_edge_required\" },\n createdBy: args.createdBy,\n createdAt: now,\n updatedAt: now,\n projectId: cleanString(args.topicNode.projectId),\n topicId: topicGlobalId,\n tenantId: cleanString(args.topicNode.tenantId),\n workspaceId: cleanString(args.topicNode.workspaceId),\n fromNodeType: \"belief\",\n toNodeType: \"topic\",\n fromLayer: \"L3\",\n toLayer: args.topicNode.epistemicLayer ?? \"ontological\",\n } as any);\n }\n\n await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {\n globalId: edgeGlobalId,\n fromGlobalId: args.beliefGlobalId,\n toGlobalId: topicGlobalId,\n edgeType: \"scoped_by\",\n weight: 1,\n confidence: 1,\n context: \"Belief creation topic anchor invariant.\",\n projectId: cleanString(args.topicNode.projectId),\n topicId: topicGlobalId,\n createdBy: args.createdBy,\n fromNodeType: \"belief\",\n toNodeType: \"topic\",\n fromLayer: \"L3\",\n toLayer: args.topicNode.epistemicLayer ?? \"ontological\",\n metadata: { invariant: \"belief.topic_edge_required\" },\n });\n}\n"]}
|
|
@@ -13,18 +13,32 @@ import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
|
|
|
13
13
|
var BELIEF_STATUS_VALUES = [
|
|
14
14
|
"assumption",
|
|
15
15
|
"hypothesis",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"confirmed",
|
|
21
|
-
"disconfirmed",
|
|
22
|
-
"partial",
|
|
23
|
-
"expired"
|
|
16
|
+
"active",
|
|
17
|
+
"superseded",
|
|
18
|
+
"resolved_true",
|
|
19
|
+
"resolved_false"
|
|
24
20
|
];
|
|
25
21
|
function isBeliefLifecycleStatus(value) {
|
|
26
22
|
return typeof value === "string" && BELIEF_STATUS_VALUES.includes(value);
|
|
27
23
|
}
|
|
24
|
+
function normalizeLegacyBeliefStatus(value) {
|
|
25
|
+
if (isBeliefLifecycleStatus(value)) {
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
if (value === "belief" || value === "established" || value === "emerging") {
|
|
29
|
+
return "active";
|
|
30
|
+
}
|
|
31
|
+
if (value === "fact" || value === "confirmed") {
|
|
32
|
+
return "resolved_true";
|
|
33
|
+
}
|
|
34
|
+
if (value === "disconfirmed" || value === "expired") {
|
|
35
|
+
return "resolved_false";
|
|
36
|
+
}
|
|
37
|
+
if (value === "deprecated") {
|
|
38
|
+
return "superseded";
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
28
42
|
function normalizeBeliefConfidence(confidence) {
|
|
29
43
|
if (typeof confidence !== "number" || !Number.isFinite(confidence)) {
|
|
30
44
|
return null;
|
|
@@ -44,47 +58,61 @@ function isResolvedByConfidence(confidence) {
|
|
|
44
58
|
}
|
|
45
59
|
return normalized <= 0 || normalized >= 1;
|
|
46
60
|
}
|
|
47
|
-
function
|
|
61
|
+
function getPredictionMetaFromMetadata(metadata) {
|
|
62
|
+
return metadata?.predictionMeta;
|
|
63
|
+
}
|
|
64
|
+
function resolvedPredictionStatus(predictionMeta) {
|
|
48
65
|
if (!predictionMeta || typeof predictionMeta !== "object") {
|
|
49
|
-
return
|
|
66
|
+
return null;
|
|
50
67
|
}
|
|
51
68
|
const outcome = predictionMeta.outcome;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
69
|
+
if (outcome === "confirmed") {
|
|
70
|
+
return "resolved_true";
|
|
71
|
+
}
|
|
72
|
+
if (outcome === "disconfirmed" || outcome === "expired") {
|
|
73
|
+
return "resolved_false";
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
56
76
|
}
|
|
57
|
-
function
|
|
77
|
+
function shouldTreatBeliefAsResolved(opts) {
|
|
58
78
|
if (isResolvedByConfidence(opts.confidence)) {
|
|
59
|
-
|
|
79
|
+
const normalized = normalizeBeliefConfidence(opts.confidence);
|
|
80
|
+
return normalized === 0 ? "resolved_false" : "resolved_true";
|
|
60
81
|
}
|
|
61
|
-
|
|
62
|
-
|
|
82
|
+
const directPredictionStatus = resolvedPredictionStatus(opts.predictionMeta);
|
|
83
|
+
if (directPredictionStatus) {
|
|
84
|
+
return directPredictionStatus;
|
|
63
85
|
}
|
|
64
|
-
|
|
65
|
-
|
|
86
|
+
const metadataPredictionStatus = resolvedPredictionStatus(
|
|
87
|
+
getPredictionMetaFromMetadata(opts.metadata)
|
|
88
|
+
);
|
|
89
|
+
if (metadataPredictionStatus) {
|
|
90
|
+
return metadataPredictionStatus;
|
|
66
91
|
}
|
|
67
|
-
return
|
|
92
|
+
return null;
|
|
68
93
|
}
|
|
69
94
|
function resolveBeliefLifecycleStatus(opts) {
|
|
70
|
-
|
|
71
|
-
|
|
95
|
+
const resolvedStatus = shouldTreatBeliefAsResolved(opts);
|
|
96
|
+
if (resolvedStatus) {
|
|
97
|
+
return resolvedStatus;
|
|
72
98
|
}
|
|
73
99
|
const direct = opts.beliefStatus;
|
|
74
|
-
|
|
100
|
+
const normalizedDirect = normalizeLegacyBeliefStatus(direct);
|
|
101
|
+
if (normalizedDirect) {
|
|
75
102
|
const normalized = normalizeBeliefConfidence(opts.confidence);
|
|
76
|
-
if (normalized !== null && isPreValidationBeliefStatus(
|
|
77
|
-
return "
|
|
103
|
+
if (normalized !== null && isPreValidationBeliefStatus(normalizedDirect)) {
|
|
104
|
+
return "active";
|
|
78
105
|
}
|
|
79
|
-
return
|
|
106
|
+
return normalizedDirect;
|
|
80
107
|
}
|
|
81
108
|
const metaStatus = opts.metadata?.beliefStatus;
|
|
82
|
-
|
|
109
|
+
const normalizedMetaStatus = normalizeLegacyBeliefStatus(metaStatus);
|
|
110
|
+
if (normalizedMetaStatus) {
|
|
83
111
|
const normalized = normalizeBeliefConfidence(opts.confidence);
|
|
84
|
-
if (normalized !== null && isPreValidationBeliefStatus(
|
|
85
|
-
return "
|
|
112
|
+
if (normalized !== null && isPreValidationBeliefStatus(normalizedMetaStatus)) {
|
|
113
|
+
return "active";
|
|
86
114
|
}
|
|
87
|
-
return
|
|
115
|
+
return normalizedMetaStatus;
|
|
88
116
|
}
|
|
89
117
|
return "assumption";
|
|
90
118
|
}
|
|
@@ -92,13 +120,14 @@ function isPreValidationBeliefStatus(status) {
|
|
|
92
120
|
return status === "assumption" || status === "hypothesis";
|
|
93
121
|
}
|
|
94
122
|
function promoteBeliefStatusAfterScoring(status, opts) {
|
|
95
|
-
|
|
96
|
-
|
|
123
|
+
const resolvedStatus = shouldTreatBeliefAsResolved({ ...opts });
|
|
124
|
+
if (resolvedStatus) {
|
|
125
|
+
return resolvedStatus;
|
|
97
126
|
}
|
|
98
127
|
if (isPreValidationBeliefStatus(status)) {
|
|
99
|
-
return "
|
|
128
|
+
return "active";
|
|
100
129
|
}
|
|
101
|
-
return status
|
|
130
|
+
return status;
|
|
102
131
|
}
|
|
103
132
|
var api = anyApi;
|
|
104
133
|
componentsGeneric();
|
|
@@ -453,7 +482,7 @@ function buildBeliefConfidenceRow(args) {
|
|
|
453
482
|
disbelief: args.disbelief,
|
|
454
483
|
uncertainty: args.uncertainty,
|
|
455
484
|
baseRate: args.baseRate,
|
|
456
|
-
slOperator: args.slOperator ?? "
|
|
485
|
+
slOperator: args.slOperator ?? "prior_seed",
|
|
457
486
|
trigger: args.trigger,
|
|
458
487
|
...args.rationale ? { rationale: args.rationale } : {},
|
|
459
488
|
assessedBy: args.assessedBy,
|
|
@@ -980,17 +1009,17 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
980
1009
|
status: 404,
|
|
981
1010
|
code: "NOT_FOUND",
|
|
982
1011
|
invariantCode: "belief.exists",
|
|
983
|
-
suggestion: "Verify nodeId points to an existing node before
|
|
1012
|
+
suggestion: "Verify nodeId points to an existing node before appending SL scoring.",
|
|
984
1013
|
details: { nodeId: args.nodeId }
|
|
985
1014
|
});
|
|
986
1015
|
}
|
|
987
1016
|
if (node.nodeType !== "belief") {
|
|
988
1017
|
throwStructuredMutationError({
|
|
989
|
-
message: `
|
|
1018
|
+
message: `appendSlScoring only applies to belief nodes. Received nodeType "${node.nodeType}". Entity nodes (company, person, investor, etc.) do not have confidence \u2014 use entityLifecycle.updateEntityAttributes for mutable entity data.`,
|
|
990
1019
|
status: 400,
|
|
991
1020
|
code: "INVALID_ARGUMENT",
|
|
992
1021
|
invariantCode: "entity.no_confidence",
|
|
993
|
-
suggestion: "Use entityLifecycle.updateEntityAttributes for entity mutations.
|
|
1022
|
+
suggestion: "Use entityLifecycle.updateEntityAttributes for entity mutations. appendSlScoring is for belief nodes only.",
|
|
994
1023
|
details: { nodeId: args.nodeId, nodeType: node.nodeType }
|
|
995
1024
|
});
|
|
996
1025
|
}
|
|
@@ -1000,7 +1029,7 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1000
1029
|
status: 400,
|
|
1001
1030
|
code: "MISSING_SCOPE",
|
|
1002
1031
|
invariantCode: "belief.project_required",
|
|
1003
|
-
suggestion: "Belief must have a projectId
|
|
1032
|
+
suggestion: "Belief must have a projectId before SL scoring can be appended.",
|
|
1004
1033
|
details: { nodeId: args.nodeId }
|
|
1005
1034
|
});
|
|
1006
1035
|
}
|
|
@@ -1023,7 +1052,7 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
1023
1052
|
status: 409,
|
|
1024
1053
|
code: "CONFLICT",
|
|
1025
1054
|
invariantCode: "belief.confidence_append_only",
|
|
1026
|
-
suggestion: "Complete a worktree linked to this belief before recording
|
|
1055
|
+
suggestion: "Complete a worktree linked to this belief before recording SL scoring.",
|
|
1027
1056
|
details: { nodeId: args.nodeId }
|
|
1028
1057
|
});
|
|
1029
1058
|
}
|
|
@@ -1476,7 +1505,7 @@ async function evaluateBuiltInEvidentialContract(args) {
|
|
|
1476
1505
|
observedValue: snapshot.value,
|
|
1477
1506
|
operator: config.operator,
|
|
1478
1507
|
threshold: config.threshold,
|
|
1479
|
-
action: config.action ?? "
|
|
1508
|
+
action: config.action ?? "append_sl_scoring",
|
|
1480
1509
|
actionParams: config.actionParams
|
|
1481
1510
|
}
|
|
1482
1511
|
};
|