# 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:
| 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`](https://crates.io/crates/serde) -- serialization/deserialization
- [`serde_json`](https://crates.io/crates/serde_json) -- JSON canonical serialization
- [`blake3`](https://crates.io/crates/blake3) -- content digest hashing
- [`uuid`](https://crates.io/crates/uuid) -- UUID v4 ID generation
- [`chrono`](https://crates.io/crates/chrono) -- timestamp support
- [`schemars`](https://crates.io/crates/schemars) -- JSON Schema generation for all types
## Usage
```rust
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