iwe
Added
refs_textmarkdown option —preserve(default) keeps each markdown link's text as written;normalizemakesiwe normalizeand document output rewrite the text to the linked document's title.iwe stats similarity— list mutually near-identical page pairs across the store, each pair once and tab-separated in alphabetical order (forward matches computed once per page, concurrently).iwe statsgains anOrphanssection listing every page with no incoming links (indexpages are exempt as intentional entry points); per-document stats (-k) gain aSimilar pageline (markdown) /similarPagesarray (JSON/YAML) of near-identical documents.iwe schema validate— validate documents against the schemas bound to them by the[schemas]config section (each entry names a schema file in.iwe/schemas/and a glob that binds it to document keys). Reports violations as-f text(default) or-f json, and accepts the universal filter flags to scope the check. Exits1when any document has violations,2on a config or schema-file error,0when clean. Bareiwe schemastill infers the frontmatter schema.iwe schema validate --schema-file <PATH>— validate the selected documents (-kor the filter flags) against a schema file directly, bypassing the[schemas]config bindings, for ad-hoc checks; violations are reported under the file's stem.iwe schema validate --explain— print the binding trace (which section and block bound to which schema entry,additionalfor the rest) instead of validating, to see how the greedy matcher reads a document against a schema.
Changed
iwe normalizeand document rendering keep markdown link text as written by default; setrefs_texttonormalizeto rewrite each link's text to the linked document's title (previously always rewritten).update --strictanddelete --strictnow reject a write that would leave a touched document violating its bound schema, aborting with exit2and the violation report before anything is written; previously--strictenforced only the--expectguards.update --strictanddelete --strictalso print non-blocking stats warnings to stderr after the schema gate — orphan pages and dangling links across the store, plus (onupdate) near-identical pages among the changed documents. They never change the exit code or block the write.
iwes
Added
refs_textmarkdown option — set tonormalizeto make document formatting rewrite each markdown link's text to the linked document's title;preserve(default) keeps the text as written.
Changed
- Document formatting keeps markdown link text as written by default (previously each link's text was rewritten to the linked document's title on format).
iwec
Added
iwe_create,iwe_update, andiwe_query(update/delete) now return non-blocking stats warnings alongside a successful result — orphan pages, dangling links, and (on create/update) near-identical pages — aswarning:content blocks, each finding reported once per session. They never block a write; schema validation remains the only hard reject.iwe_statswith akeynow returns asimilarPagesarray of documents near-identical to that page.
Changed
- Markdown link text in rendered document content is kept as written by default; set the
refs_textmarkdown option tonormalizeto rewrite each link's text to the linked document's title as before. - Mutating tools (
iwe_create,iwe_update,iwe_delete,iwe_query,iwe_rename,iwe_extract,iwe_inline,iwe_attach) now reject a change that would leave a touched document violating its bound schema, returning a detailed error carrying the readable report and a structuredviolationspayload; nothing is written and the in-memory graph is left untouched.iwe_normalizeandiwe_squashare unaffected.
liwe
Added
refs_textfield onMarkdownOptionsandDjotOptions— aRefsText(preserveby default, ornormalize) that controls whether a regular markdown link's text is rewritten to the linked document's title; read throughFormatOptions::refs_text(), withInlinesContextandGraphgainingnormalize_ref_text.schemamodule — document-schema validation:compile_schemacompiles a YAML/JSON schema (frontmatter JSON Schema plus an ordered section tree withheader,maxTokens,maxDepth,minContains/maxContains,allSections,additionalSections) into aCompiledSchema, andCompiledSchema::validatechecks aDocumentand returnsViolations carrying a breadcrumb, hint, schema pointer, and keyword. Unknown keywords are load errors (SchemaError).schemavalidation reaches block content: the document and every section, quote, and list item carryblocks/additionalBlocks/allBlocks— an ordered, greedy-matched array of block schemas discriminated bytype(paragraph,bullet-list,ordered-list,code,quote,table,rule, or a list of these for a disjunction), each withtext/langidentity,maxTokens,minContains/maxContains, listitems/minItems/maxItems, and quote/item recursion;DocumentandSectionnow carry ablocks: Vec<Block>field andCrumbgainsBlock(usize)/Item(usize). An inclusion link is matched as aparagraph.CompiledSchema::explainrenders the binding trace — which section and block bound to which schema entry,additionalfor the rest — for aDocument. Asectionsorblocksarray with an unreachable entry (a wildcard that is not last, or an exact duplicate of an earlier entry) is a load error.
Changed
- A regular markdown link's text is kept as written when rendering a document; set
refs_texttonormalizeto re-derive it from the linked document's title (previously the text was always re-derived).
diwe
Added
config::RefsTextre-export and therefs_textfield it sits on (MarkdownOptions/DjotOptions) — selects whether a markdown link's text is preserved (default) or normalized to the linked document's title.statsfindings functions —graph_findings(whole-store orphan and dangling-linkFindings, discriminated byRule) andmutation_findings(the same plus a similar-page check for the created/updated keys), withorphan_keysand the now-publicbroken_linksbehind them.stats::SimilarityIndex— a search index plus per-key token counts, built once per run (SimilarityIndex::build) and reused forsimilar(key)(near-identical pages for one key, asstats::SimilarPage { key, score }) andpairs()(every mutually-similar pair across the store, each once, computed concurrently). Duplicate detection uses mutual BM25 similarity with a token-size gate and a high threshold.GraphStatistics.orphans— the list of orphan keys behind the existingorphaned_documentscount;stats::KeyStatisticsReportpairs aKeyStatisticswith its similar pages.indexpages (rootindexor any<dir>/index) are treated as intentional entry points and excluded from both the orphan list and the count.search::Bm25Indexpoint-score API —similar_to(key, floor)(documents whose self-normalized score againstkey's own embedding clears a floor, self excluded),self_score(key), andscore_between(query_key, doc_key);search_query::corpus_textis now public.[schemas]config binding —config::SchemaBindingandconfig::Patternstypes and theConfiguration.schemasmap bind document schemas to document keys by glob (a single glob or a list). The newschemamodule resolves and runs them:schema::SchemaBindingsmatches a key to its schema names, andschema::validate_documentscompiles the bound schema files, validates a set of documents, and returns aschema::KeyReportper(key, schema)with violations.schema::validate_pending_documents(andschema::validate_pending_documents_in, which takes an explicit schemas directory) validate a set of pending(Key, content)documents against their bound schemas by building a throwaway graph, so a change can be checked before it is written.schema::pending_from_changescollects the touched documents from aChangesset,schema::render_reports_textrenders aKeyReportlist as text, andconfig::schemas_dir_inresolves the schemas directory under a given base path.schema::validate_documents_against_file— validate documents against one schema file directly, ignoring the[schemas]config bindings; reports are keyed by the file's stem.
Changed
searchnow orders tied scores deterministically (score descending, then key ascending); previously ties came back in arbitrary order.