KeiSeiKit-1.0/_primitives/_rust/kei-atom-discovery/src/lib.rs
Parfii-bot 15bf40196b feat(stream-g): kei-sage rules integration — atoms + rules unified graph
Unify atoms and rules in kei-sage's graph. Previously [[rules/...]]
wikilinks were filtered (explicit Stream C scope-deferral). Now they
resolve to rule-node units with rule_ref edges.

kei-atom-discovery extension (non-breaking):
- WikilinkTarget enum: Atom(String) | Rule(String) | Other(String)
- classify_wikilink(inner: &str) -> WikilinkTarget — exposed via lib.rs
- parse_wikilink unchanged for backwards-compat; new callers use
  classify for richer semantics

kei-sage additions:
- rule_index.rs (129 LOC) — RuleRecord + discover_rules walking flat
  *.md + extract_h1 for display name + index_rules (unit_type="rule",
  vault_path="rule:<slug>") + index_rule_edges (walks atom.related,
  emits rule_ref edges atom → rule node)
- atom_cli.rs: cmd_rules_discover + default_rules_root
- main.rs: AtomsRulesDiscover subcommand with --rules-root flag
- tests/rules_smoke.rs: 5 tests (discovery, heading extraction,
  slug fallback for headingless files, empty-dir, atom→rule edge
  persistence)

Tests: 12/12 kei-atom-discovery (+3 classify_wikilink),
28/28 kei-sage (+5 rules_smoke + unit tests now counted).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 01:21:00 +08:00

24 lines
919 B
Rust

//! kei-atom-discovery — shared substrate-atom discovery primitives.
//!
//! Single authoritative implementation of:
//! - `AtomMeta` / `AtomKind` / `SideEffect` — locked frontmatter schema
//! - `parse_frontmatter` — YAML split with 64 KiB cap (billion-laughs guard)
//! - `discover_atoms` — walks `<root>/*/atoms/*.md`, symlink-safe
//! - `parse_wikilink` — strict `[[target]]` matcher
//! - `safe_join` — path-traversal-safe base+rel join
//!
//! Both `kei-sage` and `kei-runtime` consume this crate — no parallel
//! frontmatter structs, no parallel YAML parsers.
pub mod error;
pub mod frontmatter;
pub mod walk;
pub use error::Error;
pub use frontmatter::{
parse_frontmatter, AtomKind, AtomMeta, Frontmatter, SideEffect, MAX_FRONTMATTER_BYTES,
};
pub use walk::{
classify_wikilink, discover_atoms, is_atom_target, parse_wikilink, safe_join, split_atom_id,
WikilinkTarget,
};