stack-ids 0.1.0

Shared identity, scope, and trace primitives for the local-first AI systems stack
Documentation

stack-ids

Shared identity, scope, and trace primitives for the local-first AI systems stack.

Overview

stack-ids is the single source of truth for cross-crate identity types in the stack. It provides opaque ID newtypes, multi-dimensional scope partitioning, W3C-compatible trace context, and canonical BLAKE3 content digests.

This crate defines type contracts only — it does not own the data these IDs point to, storage schemas, or business logic. Those responsibilities belong to their respective domain crates.

Modules

ids — Opaque ID Newtypes

218 opaque string-wrapper ID types generated via define_id! macro. Each type provides:

  • new() / generate() (UUID v4) / as_str() / is_empty()
  • Display, FromStr, From<String>, From<&str>, AsRef<str>
  • Serialize / Deserialize (serde transparent)
  • JsonSchema (schemars)
  • Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord

ID families span the full artifact taxonomy:

Family Examples
Core EnvelopeId, ClaimId, ClaimVersionId, EntityId, EpisodeId
Retry/Execution AttemptId, TrialId, KernelRunId, ExecutionPermitId
Projection ProjectionId, RelationId, RelationVersionId, ImportBatchId
Grouping ClaimFamilyId, AssertionGroupId, RelationGroupId, ContradictionGroupId
Kernel ConstraintId, HyperedgeId, ResidualId, SyndromeId, WitnessId, CertificateId
Verification/Control VerificationCaseId, CheckPlanId, ControlReceiptId, PolicyDecisionId
Governance ApprovalGrantId, PromotionDecisionId, RollbackPlanId, CalibrationSnapshotId
Semantic SemanticsProfileId, ClaimStateId, SemanticDiffId, SupportSetId
Experiment InterventionId, ExperimentCaseId, CohortContractId, DecisionTraceId
Attestation AttestationEnvelopeId, TrustRootSetId, TransparencyReceiptId
Effect EffectIntentId, EffectWindowId, EffectCommitDecisionId, CompensationPlanId
Authority CapabilityClassId, AuthorityLeaseId, DelegationBundleId, BreakGlassGrantId
Release/Safety DeploymentProfileId, AssuranceCaseId, HazardRegisterId, CertificationBundleId
Incident IncidentCaseId, ForensicFreezeId, RecoveryPlanId, PostmortemBundleId
Treaty/Settlement TreatyBundleId, SettlementCaseId, SharedDispositionId
Theory/Discovery TheoryVersionId, SimulationContractId, DiscoveryProgramId
Constitution CharterBundleId, DoctrineSnapshotId, AmendmentProposalId
Spec/Schema SpecBundleId, NormativeAstId, GeneratedSchemaBundleId
Privacy/Compliance PrivacyRetentionProfileId, RedactionRuleSetId, ResidencyPolicyProfileId
Policy Profiles EffectPolicyProfileId, DelegationPolicyProfileId, ReleasePolicyProfileId

scope — Multi-Dimensional Scope Partitioning

  • Scope — builder-pattern struct with namespace, optional domain, workspace_id, and repo_id.
  • ScopeKey — compact, hashable, orderable partition key. Display format: namespace[/domain][@workspace_id][#repo_id].
  • PhaseStatus — enum (Current, Compatibility, PhaseGated) for feature lifecycle tracking.
  • Legacy namespace migration via ScopeKey::from_legacy_namespace() / to_legacy_namespace().

trace — W3C Trace Context

  • TraceCtx — in-process trace context with trace_id, optional parent_id, and bounded baggage (max 16 entries, 256 bytes per key/value).
  • W3C traceparent header serialization/deserialization (to_traceparent() / from_traceparent()).
  • Non-W3C trace IDs are converted via deterministic BLAKE3 hash truncation (hash_to_w3c_trace_id()).
  • Child span creation with child().
  • TraceError — error type for baggage limits and invalid traceparent headers.

digest — Canonical BLAKE3 Content Digest

  • ContentDigest — BLAKE3 hash as 64-char hex string. Compute from bytes, strings, or JSON-serializable values.
  • DigestBuilder — incremental hasher with field separators for multi-field digest domains.
  • Canonical JSON serialization with recursive key normalization for deterministic hashing regardless of map key order.
  • DigestError — error type for serialization failures and invalid digest strings.

status — Surface Status

  • SurfaceStatus — shared publication-status enum (AdvisoryOnly, NonAdmitted, Degraded, HorizonOnly) for governance profile surfaces.

v25 — V25 Constitution Citation

  • V25ConstitutionCitation — canonical constitutional citation struct referencing ApplicabilityContextId, ProfileSetId, CompositionReceiptId, EffectiveConstitutionId, CompiledObligationSetId, and optional conflict/exception IDs.

Ecosystem

Depends on: (no sibling crate path dependencies -- this is the identity foundation)

Depended on by: nearly every crate in the workspace, including:

  • semantic-memory, semantic-memory-forge, forge-memory-bridge
  • constraint-compiler, kernel-execution, kernel-oracles, recursive-kernel-core
  • knowledge-runtime, forge-pilot, kernel-conformance
  • verification-control, verification-policy, verification-calibration, verification-adjudication
  • discovery-portfolio, federated-settlement, constitutional-memory
  • mechanism-runtime, effect-runtime, attestation-exchange
  • spec-execution, remote-oracle-admission, profile-runtime
  • llm-tool-runtime, forge-engine (living-memory)

stack-ids integration

This crate IS the identity foundation. All other crates in the ecosystem import their typed ID newtypes, TraceCtx, ScopeKey, and ContentDigest from here. No other crate should define competing ID types for the same concepts.

Dependencies

  • serde -- serialization/deserialization
  • serde_json -- JSON canonical serialization
  • blake3 -- content digest hashing
  • uuid -- UUID v4 ID generation
  • chrono -- timestamp support
  • schemars -- JSON Schema generation for all types

Usage

use stack_ids::{EntityId, Scope, ScopeKey, TraceCtx, ContentDigest};

// Generate an opaque ID
let entity = EntityId::generate();
println!("{}", entity); // UUID v4 string

// Build a scoped partition key
let scope = Scope::new("prod")
    .with_domain("code")
    .with_workspace("ws1")
    .with_repo("myrepo");
let key: ScopeKey = scope.key();
assert_eq!(key.to_string(), "prod/code@ws1#myrepo");

// Create and propagate trace context
let trace = TraceCtx::generate();
let child = trace.child("abcdef0123456789");
let header = child.to_traceparent().unwrap();

// Compute a content digest
let digest = ContentDigest::compute(b"hello world");
assert_eq!(digest.hex().len(), 64);

License

MIT