From cb7e719e925c09defcd9a7bace1bc0637766a5b0 Mon Sep 17 00:00:00 2001 From: Casimir Arlabosse <11591428+casiar@users.noreply.github.com> Date: Tue, 27 Oct 2026 15:46:28 +0800 Subject: [PATCH 1/2] test: resolve golden fixture path with import.meta.dirname new URL(import.meta.url).pathname keeps percent-encoding, so the test failed with ENOENT when the checkout path contains a space. Use import.meta.dirname like the other tests. Co-Authored-By: Claude Opus 5.5 --- tests/schema-stamps.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/schema-stamps.test.ts b/tests/schema-stamps.test.ts index bfb1cd3..acb4cda 100644 --- a/tests/schema-stamps.test.ts +++ b/tests/schema-stamps.test.ts @@ -110,7 +110,7 @@ test("render-settings: its write stamps the family sidecar too", () => { // ── the fixtures stay the legacy pin: golden data reads unstamped ─────────── test("golden fixtures are deliberately the unstamped legacy shape (lazy v1 = current-valid)", () => { - const here = path.dirname(new URL(import.meta.url).pathname); + const here = import.meta.dirname; const teach = JSON.parse(fs.readFileSync(path.join(here, "fixtures", "golden-data", "chats", "chat_mv27rrra_feff23b6.json"), "utf8")); assert.equal(teach.version, undefined, "fixture records pin the unstamped read path"); assert.ok(!fs.existsSync(path.join(here, "fixtures", "golden-data", "graph", "format.json")), "no sidecar in the fixture graph dir"); From 8ad17a4fe4db2cd1dde9a22e0651c0035e4d7f53 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 27 Oct 2026 15:18:44 +0100 Subject: [PATCH 2/2] docs: fix relative links in development guide --- docs/architecture.md | 2 +- docs/development.md | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index 627758c..6d1e28f 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,6 +1,6 @@ # Learning Harness — Architecture -Status: **the canonical architecture spec** — describes the as-built system, verified against the code by a full audit on 2026-09-18 (every file under `src/`, `app/`, `components/`, `electron/`, `scripts/`, the lint config, and the test suite; `lint` and `typecheck` clean on the audited tree). The pre-audit spec is archived at [`archive/architecture-2026-09-08.md`](archive/architecture-2026-09-08.md) — history only. Product reasoning lives in [`docs/vision.md`](vision.md); file-by-file layout lives in the README. +Status: **the canonical architecture spec** — describes the as-built system, verified against the code by a full audit on 2026-09-18 (every file under `src/`, `app/`, `components/`, `electron/`, `scripts/`, the lint config, and the test suite; `lint` and `typecheck` clean on the audited tree). The pre-audit spec is archived at [`docs/archive/architecture-2026-09-08.md`](archive/architecture-2026-09-08.md) — history only. Product reasoning lives in [`docs/vision.md`](vision.md); file-by-file layout lives in the README. **What this is.** A standalone learning app (web + Electron desktop): the learner's knowledge accumulates into one persistent, cross-session knowledge graph, built from tutoring sessions in which a teacher agent authors a formal, visible dependency tree (the plan tree) and verifies understanding with structured questions. The graph is the home page; the session is the classroom; everything else serves those two. diff --git a/docs/development.md b/docs/development.md index 1859053..4c81a84 100644 --- a/docs/development.md +++ b/docs/development.md @@ -2,13 +2,13 @@ The developer README (split out of the storefront README, 2026-10-10). Everything below is for people working ON LearnHarness, not using it. -A standalone learning app (web + Electron desktop): a **teacher agent** (Next.js; the Vercel AI SDK's `UIMessage` protocol end-to-end, LLM engine [pi-ai](docs/pi-engine-swap.md) via OpenRouter), probe→teach lessons with graded quiz/ask interactions, a formal **session plan tree** the teacher authors once (`plan_init`) and whose progress is derived from tagged quiz calls, and a persistent cross-session **knowledge graph** of what the learner knows — the graph is the app's home page. +A standalone learning app (web + Electron desktop): a **teacher agent** (Next.js; the Vercel AI SDK's `UIMessage` protocol end-to-end, LLM engine [pi-ai](pi-engine-swap.md) via OpenRouter), probe→teach lessons with graded quiz/ask interactions, a formal **session plan tree** the teacher authors once (`plan_init`) and whose progress is derived from tagged quiz calls, and a persistent cross-session **knowledge graph** of what the learner knows — the graph is the app's home page. Not a chat app with a graph bolted on: sessions are probe→teach lessons, the plan tree is a structured, schema-validated object, sessions accumulate into the graph through the extraction pipeline (propositions + reasoning chains — the stored truth; the canvas renders a derived image), and the teacher reaches back into the graph through read-only prober tools on its own judgment so probing compounds across sessions. -- [`docs/architecture.md`](docs/architecture.md) is the **canonical architecture spec** — layers, the import law, the five systems, the invariants, the seam directory. (The pre-audit spec is archived under `docs/archive/` — history only.) -- Living design doc (all decisions): [`docs/vision.md`](docs/vision.md) -- Build plan + wave/gate results: [`docs/plan.md`](docs/plan.md) +- [`docs/architecture.md`](architecture.md) is the **canonical architecture spec** — layers, the import law, the five systems, the invariants, the seam directory. (The pre-audit spec is archived under `docs/archive/` — history only.) +- Living design doc (all decisions): [`docs/vision.md`](vision.md) +- Build plan + wave/gate results: [`docs/plan.md`](plan.md) ## Commands @@ -33,7 +33,7 @@ npx tsx --env-file=.env.local scripts/backfill-graph.ts # wipe + re-extrac npx tsx --env-file=.env.local scripts/replay-layout.ts # re-derive layout from the ledgers ``` -For Windows/Linux packages and the three-OS CI/release flow, see [`desktop-release.md`](desktop-release.md). Native renderer binaries are traced per platform, so release builds run on the target OS, not as cross-builds from macOS. +For Windows/Linux packages and the three-OS CI/release flow, see [`docs/desktop-release.md`](desktop-release.md). Native renderer binaries are traced per platform, so release builds run on the target OS, not as cross-builds from macOS. ## Environment (`.env.local`) @@ -60,7 +60,7 @@ This remains a **trusted developer/shared-server mode**, not multi-user hosting. ## Architecture -Five layers, dependency arrows pointing inward only, machine-enforced as four ESLint zones (shell → barrels only; core and agent never import below themselves). Two composition roots, one writer per store. The full spec — layers, systems, runtime flows, invariants, seams: [`docs/architecture.md`](docs/architecture.md). +Five layers, dependency arrows pointing inward only, machine-enforced as four ESLint zones (shell → barrels only; core and agent never import below themselves). Two composition roots, one writer per store. The full spec — layers, systems, runtime flows, invariants, seams: [`docs/architecture.md`](architecture.md). ```mermaid flowchart TB @@ -190,7 +190,7 @@ All deterministic, no LLM, no network (engines are injected — pi-ai's faux pro ## Lineage -The teaching methodology comes from an Obsidian-based POC (its `knowledge graph design.md` was the original epistemic-model source, since amended — see the amendments table in `docs/vision.md`). The harness was originally built on the pi agent SDK, pivoted to standalone Next.js + the Vercel AI SDK, and later swapped its LLM engine back to pi-ai while keeping the AI SDK's `UIMessage` as the client protocol ([`docs/pi-engine-swap.md`](docs/pi-engine-swap.md)). +The teaching methodology comes from an Obsidian-based POC (its `knowledge graph design.md` was the original epistemic-model source, since amended — see the amendments table in `docs/vision.md`). The harness was originally built on the pi agent SDK, pivoted to standalone Next.js + the Vercel AI SDK, and later swapped its LLM engine back to pi-ai while keeping the AI SDK's `UIMessage` as the client protocol ([`docs/pi-engine-swap.md`](pi-engine-swap.md)). ## Data