sealmap
Deterministic code maps for LLM development harnesses: the facade and command-line tool of sealmap.
sealmap reads source without compiling it, builds a language-neutral model
(symbols, relations, the ordered call flow of every function) and projects it
into Mermaid diagrams with one document per source file. The same sources
always give byte-identical output. Every symbol has a stable sym: id (no
file path) and two fingerprints: sig_hash for its contract, body_hash for
its implementation, both blind to formatting, comments and moves.
Hand-written diagram topics cite those ids, and a lockfile, seals.lock,
records the hashes each cited symbol had when the topic was reviewed.
sealmap verify checks every seal against the code in CI, with no LLM
involved, and sealmap stale lists only the topics whose sealed symbols
changed. sealmap dense writes a compact agent projection of the code, and
sealmap pack a bounded review pack of chosen topics with the code they
cite (see the
design).
| Crate | Role |
|---|---|
sealmap-model |
language-neutral code model |
sealmap-mermaid |
typed Mermaid writers and injective diagram ids (no dependencies without the default model feature) |
sealmap-extract |
logic shared by every language adapter (replaces sealmap-frontend, now a deprecated forwarding shim) |
sealmap-rust |
Rust language adapter (syn) |
sealmap-corpus |
projections, index and write; the seal lock, verify, seal_check, stale, resolve, sign; review packs (pack) |
sealmap-dense |
compact agent projection: skeletons, call trees, short-name index, budgeted slices (sealmap::dense) |
Command line
# Seals over the authored topics in docs/diagrams/ (lock: docs/diagrams/seals.lock)
# Review packs: topics, dense slices of the code they cite, source windows
Exit codes: 0 success; 1 a check failed, an id is not found, or a seal was refused; 2 usage or IO error.
Library
use Path;
let corpus = generate_dir?;
let report = write?;
println!;
# Ok::
Ids and fingerprints, on sources held in memory:
use ;
use ;
let mut src = new;
src.insert.unwrap;
let model = extract.codebase;
let id = parse.unwrap;
let get = model.symbol.unwrap;
assert!;
// Reformatting and comments change neither fingerprint.
let mut again = new;
again.insert.unwrap;
let model2 = extract.codebase;
let get2 = model2.symbol.unwrap;
assert_eq!;
Sealing in memory, and catching a behaviour change:
use ;
use SourcePath;
use ;
let opts = RustOptions ;
let model = ;
let file = new.unwrap;
let topic = "---\nid: ST-01\n---\nReads go through `sym:cargo shop . Db#get().`.\n";
let who = Signature ;
let mut lock = new;
let sealed = sign.unwrap;
let topics = .into_iter.collect;
let lock_text = lock.to_toml;
assert!;
let report = verify;
assert_eq!;
Licence
Licensed under either of Apache License, Version 2.0 or MIT licence, at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 licence, shall be dual licensed as above, without any additional terms or conditions.