Skip to content

feat(knowledge): warn at write time when a note lands off-schema - #1687

Open
elhoim wants to merge 3 commits into
danielmiessler:mainfrom
elhoim:feat/knowledge-write-guard
Open

feat(knowledge): warn at write time when a note lands off-schema#1687
elhoim wants to merge 3 commits into
danielmiessler:mainfrom
elhoim:feat/knowledge-write-guard

Conversation

@elhoim

@elhoim elhoim commented Jul 28, 2026

Copy link
Copy Markdown

Stacks on #1686. That PR reports non-conformance on the Stop pass. This one reports it at the write, while the author is still in the loop and the fix is one edit rather than a migration.

Why a write-time signal

MemorySystem.renderInitialNote is the sanctioned way a note is born on the schema. Nothing prevents a writer from bypassing it.

A bulk import did exactly that and wrote 1,744 notes off-schema. Every writer afterwards read a neighbouring note, copied its frontmatter, and spread the legacy dialect further — including, on the archive where this was found, two agents that were explicitly trying to match house style. Copying a sibling is the intuitive move, and it is precisely the wrong one.

The convention was documented and unenforced. This is the smallest thing that makes it visible at the point of failure.

Contract

  • Advisory only. Emits additionalContext naming the violations and pointing at renderInitialNote.
  • Never blocks. The note is already on disk by PostToolUse, and a hard gate on note-writing would be worse than the drift it prevents.
  • Narrow. Silent for every path outside MEMORY/KNOWLEDGE/<Type>/*.md, including _index.md and _schema.md.
  • Validates in-process via KnowledgeSchema.validate() — one file, no subprocess.

Verified

Input Result
Conformant note silent
_schema.md silent
Ideas/_index.md silent
settings.json path silent
Note downgraded to convention: kb-v2 warns, names the violation, gives the repair route

The warning it emits:

⚠ Knowledge note written off-schema — `Ideas/<slug>.md`
  - `convention` — not kb-v3 (dialect not migrated)

Notes are born on the schema via `MemorySystem.renderInitialNote`. Do not
hand-write frontmatter by copying a sibling — that is how a legacy dialect
spreads. Fix this note now, or run `bun LIFEOS/TOOLS/MigrateKnowledge.ts`
(dry-run by default) for a bulk repair.

The set

Four PRs close this end to end: #1684 fixes a rule that could never be satisfied, #1685 stops the doc drifting from the code, #1686 makes note-level drift visible, and this makes it visible at the moment it happens.

elhoim added 3 commits July 28, 2026 07:15
GenerateKnowledgeSchemaDoc.ts is currently dead code — nothing invokes it.
Two consequences: _schema.md does not exist on a fresh install, and where it
does exist it drifts from KnowledgeSchema.ts, which is the declared source
of truth.

That drift is not theoretical. On the archive this was found on, _schema.md
declared kb-v3 while describing 0.9% of the notes it governed, and the gap
went unnoticed because nothing regenerated the doc.

Wire the generator into DocIntegrity so the doc is rebuilt from the schema
on every integrity pass. Fire-and-forget, non-fatal on failure, and run as
a subprocess rather than imported because the generator executes main() on
import.
RebuildKnowledgeSchema (danielmiessler#1685) keeps _schema.md honest against
KnowledgeSchema.ts, so the DOC can no longer drift from the CODE. Nothing
checks whether the NOTES conform to either.

That gap is how an archive reached 0.9% conformance without a single
warning: a bulk import wrote 1,744 notes off-schema, later writers copied
their frontmatter and spread the dialect, and KnowledgeLint — the one tool
that could have said so — is invoked by nothing in the tree. It only ever
runs when a human remembers to type it.

Add a read-only conformance check alongside the regen. It calls validate()
from KnowledgeSchema directly rather than shelling out, reports a
percentage plus the top violation classes, names the repair command
(MigrateKnowledge.ts), and emits a typed event for Pulse.

Reports only. Never edits, never blocks — non-conformance is a soft
warning, matching MemoryDirIntegrity's contract.

Verified on a 1,801-note archive: reports 100.0% clean, and a deliberately
downgraded note is caught as '1x convention — not kb-v3'.

Stacks on danielmiessler#1685.
MemorySystem.renderInitialNote is the sanctioned way a note is born on the
schema, but nothing prevents a writer from bypassing it. A bulk import did
exactly that and wrote 1,744 notes off-schema; every writer afterwards read
a neighbouring note, copied its frontmatter, and spread the legacy dialect
further. The convention was documented and unenforced.

danielmiessler#1686 reports the damage on the Stop pass. This reports it at the write,
while the author is still in the loop and the fix is one edit instead of a
migration.

Advisory only. Emits additionalContext naming the violations and pointing
at renderInitialNote; never blocks, because the note is already on disk by
PostToolUse and a hard gate on note-writing would be worse than the drift.
Silent for every path outside MEMORY/KNOWLEDGE/<Type>/*.md, including
_index.md and _schema.md.

Verified: silent on a conformant note, silent on _schema.md, _index.md and
a settings.json path, and on a note downgraded to kb-v2 it emits the
violation plus the repair route.

Stacks on danielmiessler#1686.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant