Graph nodes gain a name; nodes are objective facts (no learner/session references)
Schema: GraphNode + ExtractedProposition carry 'name' — a short 2-6 word header, the rendering handle. Node theory made explicit: a node is an objective world-facing fact; the learner's relationship to it lives entirely in the event ledger (state labels are derived, never stored). Extractor + auditor instructions enforce it — misconceptions state the wrong idea itself as a claim, never 'the learner believes Y'. Legacy ledger lines without a name derive one from the statement on read. graph-view: labels use the name; the detail panel shows name as header and statement as body.
This commit is contained in:
@@ -135,6 +135,7 @@ const FINDINGS: SessionFindings = {
|
||||
propositions: [
|
||||
{
|
||||
id: "p1",
|
||||
name: "Chain rule",
|
||||
statement: "Chain rule intuition",
|
||||
aliases: [],
|
||||
kind: "truth",
|
||||
@@ -143,6 +144,7 @@ const FINDINGS: SessionFindings = {
|
||||
},
|
||||
{
|
||||
id: "p2",
|
||||
name: "Applying chain rule",
|
||||
statement: "Applying the chain rule",
|
||||
aliases: [],
|
||||
kind: "truth",
|
||||
|
||||
@@ -43,7 +43,7 @@ import { PATHS } from "../config.ts";
|
||||
// ─── fixtures ────────────────────────────────────────────────────────────────
|
||||
|
||||
function node(id: string, statement: string, over: Partial<GraphNode> = {}): GraphNode {
|
||||
return { id, statement, aliases: [], kind: "truth", createdAt: "2026-08-22T00:00:00.000Z", ...over };
|
||||
return { id, name: statement.split(";")[0]!, statement, aliases: [], kind: "truth", createdAt: "2026-08-22T00:00:00.000Z", ...over };
|
||||
}
|
||||
|
||||
function edge(from: string, to: string): GraphEdge {
|
||||
@@ -329,6 +329,7 @@ function treeFindings(tree: ReturnType<typeof createTree>): SessionFindings {
|
||||
return {
|
||||
propositions: tree.nodes.map((n, i) => ({
|
||||
id: `p${i + 1}`,
|
||||
name: n.title,
|
||||
statement: n.title,
|
||||
aliases: [],
|
||||
kind: "truth" as const,
|
||||
@@ -380,6 +381,7 @@ describe("exact-match merge (merger identity resolution)", () => {
|
||||
const ledgers = memoryLedgers();
|
||||
ledgers.appendNode({
|
||||
id: "n_alias",
|
||||
name: "Differentiation",
|
||||
statement: "Differentiation basics",
|
||||
aliases: ["the derivative"],
|
||||
kind: "truth",
|
||||
|
||||
+15
-1
@@ -136,6 +136,7 @@ function treeFindings(tree: PlanTree): SessionFindings {
|
||||
return {
|
||||
propositions: tree.nodes.map((n, i) => ({
|
||||
id: `p${i + 1}`,
|
||||
name: n.title,
|
||||
statement: n.title,
|
||||
aliases: [],
|
||||
kind: "truth" as const,
|
||||
@@ -428,7 +429,7 @@ describe("the trigger helper (pendingQuizAnswers)", () => {
|
||||
|
||||
describe("graph ledger store", () => {
|
||||
it("round-trips lines and skips corrupt / foreign-shaped lines (strict reads)", () => {
|
||||
const node = { id: "n_storetest", statement: "Store test", aliases: [], kind: "truth" as const, createdAt: "2026-08-22T00:00:00.000Z" };
|
||||
const node = { id: "n_storetest", name: "Store test", statement: "Store test", aliases: [], kind: "truth" as const, createdAt: "2026-08-22T00:00:00.000Z" };
|
||||
graphStore.appendNode(node);
|
||||
// A torn append and a legacy V0-shaped node (different schema) — both skipped.
|
||||
fs.appendFileSync(
|
||||
@@ -439,5 +440,18 @@ describe("graph ledger store", () => {
|
||||
const nodes = graphStore.readNodes().filter((n) => n.id === "n_storetest" || n.id === "legacy");
|
||||
assert.equal(nodes.length, 1);
|
||||
assert.equal(nodes[0]!.statement, "Store test");
|
||||
assert.equal(nodes[0]!.name, "Store test");
|
||||
});
|
||||
|
||||
it("derives a name for pre-name ledger lines (legacy reads)", () => {
|
||||
// A full, valid node line written before `name` existed.
|
||||
fs.appendFileSync(
|
||||
LEDGER_FILES.nodes,
|
||||
`${JSON.stringify({ id: "n_prename", statement: "Derivatives measure instantaneous change; they are limits.", aliases: [], kind: "truth", createdAt: "2026-08-22T00:00:00.000Z" })}\n`,
|
||||
"utf-8",
|
||||
);
|
||||
const node = graphStore.readNodes().find((n) => n.id === "n_prename");
|
||||
assert.ok(node);
|
||||
assert.equal(node.name, "Derivatives measure instantaneous change");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user