From 95f8308d4b665ac51b39497c5722aead0a533c70 Mon Sep 17 00:00:00 2001 From: elhoim Date: Tue, 28 Jul 2026 07:11:00 +0000 Subject: [PATCH] fix(knowledge): waive source_* requirements for source_kind: internal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PER_TYPE_REQUIRED demands source_url on every research note. That is wrong for notes with source_kind: internal — those have no external origin, they ARE the primary artifact (an own-prose capture, a design decision, a corpus the system itself built). The rule asks for a URL that cannot exist. On a real archive this was 10 notes permanently unable to pass lint, with nothing to backfill: none of the ten had a single URL anywhere in its body. The fix is the schema, not the notes. Skip source_* per-type requirements when source_kind is internal. Externally-sourced notes still must carry their provenance. Also teach GenerateKnowledgeSchemaDoc to emit the waiver. The generator reads PER_TYPE_REQUIRED (a data table) while the rule lives in validate(), so the generated doc would otherwise state a requirement the linter does not enforce — the same doc-vs-behaviour drift this schema exists to prevent. --- LifeOS/install/LIFEOS/TOOLS/GenerateKnowledgeSchemaDoc.ts | 2 ++ LifeOS/install/LIFEOS/TOOLS/KnowledgeSchema.ts | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/LifeOS/install/LIFEOS/TOOLS/GenerateKnowledgeSchemaDoc.ts b/LifeOS/install/LIFEOS/TOOLS/GenerateKnowledgeSchemaDoc.ts index 95972f4e7b..ad570c5367 100755 --- a/LifeOS/install/LIFEOS/TOOLS/GenerateKnowledgeSchemaDoc.ts +++ b/LifeOS/install/LIFEOS/TOOLS/GenerateKnowledgeSchemaDoc.ts @@ -69,6 +69,8 @@ function render(): string { L.push(`| \`${t}\` | ${extra.length ? extra.map((k) => `\`${k}\``).join(", ") : "— (envelope only)"} |`); } L.push(""); + L.push("**Waived for internal notes.** A note with `source_kind: internal` has no external origin — it *is* the primary artifact (an own-prose capture, a design decision, a corpus this system built). Demanding a `source_url` of it asks for a URL that cannot exist, so `source_*` requirements above are skipped when `source_kind` is `internal`. Externally-sourced notes still must carry their provenance."); + L.push(""); L.push("A note missing an optional per-type source field (e.g. a research note with no `source_url`) is **envelope-conformant but incomplete** — Lint reports it as an enrichment gap, not a schema failure."); L.push(""); diff --git a/LifeOS/install/LIFEOS/TOOLS/KnowledgeSchema.ts b/LifeOS/install/LIFEOS/TOOLS/KnowledgeSchema.ts index 4e09f836e9..3e97143367 100755 --- a/LifeOS/install/LIFEOS/TOOLS/KnowledgeSchema.ts +++ b/LifeOS/install/LIFEOS/TOOLS/KnowledgeSchema.ts @@ -488,7 +488,14 @@ export function validate(parsed: ParsedNote, _slug: string, dirType: CanonicalTy // per-type required (present AND non-empty) const effType = ((CANONICAL_TYPES as readonly string[]).includes(t ?? "") ? t : dirType) as CanonicalType; + // `source_kind: internal` means the note has no external origin — it IS the + // primary artifact (a LifeOS corpus, a design decision, an own-prose capture). + // Demanding a source_url of it asks for a URL that cannot exist, so the + // source_* requirements are waived for internal notes. Externally-sourced + // notes still must carry their provenance. + const isInternal = deq(get("source_kind")) === "internal"; for (const key of PER_TYPE_REQUIRED[effType] ?? []) { + if (isInternal && key.startsWith("source_")) continue; if (missingOrEmpty(key)) v.push({ key, problem: `required for type ${effType}` }); }