| Crates.io | specman |
| lib.rs | specman |
| version | 2.2.0 |
| created_at | 2025-12-02 19:37:18.437116+00 |
| updated_at | 2026-01-20 20:11:45.526232+00 |
| description | SpecMan runtime library for dependency mapping, templating, and lifecycle automation. |
| homepage | |
| repository | |
| max_upload_size | |
| id | 1962498 |
| size | 542,191 |
SpecMan is the runtime foundation for authoring and automating software specifications. It powers workspace discovery, dependency mapping, templating, and lifecycle workflows that keep specs consistent and reproducible.
WorkspaceLocator, WorkspacePaths)DependencyTree)TemplateCatalogMarkdownTemplateEngine)Specman façade (plan/create/delete)SpecmanError::Lifecycle(LifecycleError)) so callers can branch programmaticallyAdd the published crate to your Cargo.toml:
specman = "2"
Or with Cargo:
cargo add specman@2
The ergonomic entrypoint is DefaultSpecman, which wires the default filesystem-backed stack:
use specman::DefaultSpecman;
let specman = DefaultSpecman::from_current_dir()?;
# Ok::<(), specman::SpecmanError>(())
For automation, match lifecycle errors directly instead of parsing strings:
use specman::error::LifecycleError;
use specman::SpecmanError;
fn classify(err: SpecmanError) {
match err {
SpecmanError::Lifecycle(LifecycleError::DeletionBlocked { .. }) => {
// downstream dependents exist
}
SpecmanError::Lifecycle(LifecycleError::PlanTargetMismatch { .. }) => {
// a stale plan was supplied for a different artifact
}
_ => {}
}
}
Use the reference validator when you need to sanity-check Markdown link destinations inside a workspace. Typical flow:
use specman::{
ReferenceValidationStatus, ReferenceValidator, ValidationMode, discover_workspace,
};
let workspace = discover_workspace(".")?; // or WorkspaceDiscovery::initialize(start)
// Default mode: reachability on, fragments on, transitive traversal on (64 doc limit).
let validator = ReferenceValidator::new(&workspace);
let report = validator.validate("spec/my-spec/spec.md")?;
if report.status == ReferenceValidationStatus::Failure {
for issue in &report.issues {
eprintln!("{:?}: {}", issue.kind, issue.message);
}
}
// To tweak behavior (e.g., disable fragment checks or reachability):
let mut mode = ValidationMode::default();
mode.resolve_fragments = false; // skip heading-fragment verification
mode.reachability = specman::ReachabilityPolicy::Disabled; // syntax-only for https://
let report = ReferenceValidator::with_mode(&workspace, mode).validate("impl/foo/impl.md")?;
Intricate details to be aware of:
spec://{name}, impl://{name}, scratch://{slug}); handles found inside Markdown links are rejected as DisallowedHandle.Diagnostic, while 4xx responses become Error and fail the run.WorkspaceBoundary or FileMissing errors even if they never existed.-1, -2, ...). Cross-document fragments are validated transitively by default up to 64 Markdown documents.discovered references and issues for consumers.All source, issue tracking, and release notes live in the main GitHub repository:
https://github.com/justinbrick/specman
Star the repo or follow along for roadmap updates (including relationship graphing and expanded MCP tool coverage).