ciaf-core 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. ciaf_core-0.1.1/CHANGELOG.md +131 -0
  2. ciaf_core-0.1.1/CONTRIBUTING.md +287 -0
  3. ciaf_core-0.1.1/IDs/__init__.py +192 -0
  4. ciaf_core-0.1.1/LICENSE +176 -0
  5. ciaf_core-0.1.1/MANIFEST.in +34 -0
  6. ciaf_core-0.1.1/PKG-INFO +287 -0
  7. ciaf_core-0.1.1/QUICKSTART.md +312 -0
  8. ciaf_core-0.1.1/README.md +254 -0
  9. ciaf_core-0.1.1/__init__.py +112 -0
  10. ciaf_core-0.1.1/builders/__init__.py +333 -0
  11. ciaf_core-0.1.1/canonicalization/__init__.py +101 -0
  12. ciaf_core-0.1.1/ciaf_core.egg-info/PKG-INFO +287 -0
  13. ciaf_core-0.1.1/ciaf_core.egg-info/SOURCES.txt +66 -0
  14. ciaf_core-0.1.1/ciaf_core.egg-info/dependency_links.txt +1 -0
  15. ciaf_core-0.1.1/ciaf_core.egg-info/requires.txt +8 -0
  16. ciaf_core-0.1.1/ciaf_core.egg-info/top_level.txt +1 -0
  17. ciaf_core-0.1.1/enums.py +144 -0
  18. ciaf_core-0.1.1/example_signed_event.py +173 -0
  19. ciaf_core-0.1.1/exceptions.py +37 -0
  20. ciaf_core-0.1.1/hashing/__init__.py +153 -0
  21. ciaf_core-0.1.1/pyproject.toml +79 -0
  22. ciaf_core-0.1.1/schemas/__init__.py +29 -0
  23. ciaf_core-0.1.1/schemas/action.py +71 -0
  24. ciaf_core-0.1.1/schemas/actor.py +59 -0
  25. ciaf_core-0.1.1/schemas/event.py +134 -0
  26. ciaf_core-0.1.1/schemas/evidence.py +86 -0
  27. ciaf_core-0.1.1/schemas/execution.py +82 -0
  28. ciaf_core-0.1.1/schemas/governance.py +86 -0
  29. ciaf_core-0.1.1/schemas/lineage.py +75 -0
  30. ciaf_core-0.1.1/schemas/policy.py +95 -0
  31. ciaf_core-0.1.1/schemas/relationships.py +67 -0
  32. ciaf_core-0.1.1/schemas/resource.py +59 -0
  33. ciaf_core-0.1.1/schemas/risk.py +107 -0
  34. ciaf_core-0.1.1/schemas/signed_event.py +187 -0
  35. ciaf_core-0.1.1/schemas/subject.py +59 -0
  36. ciaf_core-0.1.1/setup.cfg +4 -0
  37. ciaf_core-0.1.1/signing/__init__.py +271 -0
  38. ciaf_core-0.1.1/utils/__init__.py +3 -0
  39. ciaf_core-0.1.1/utils/time.py +15 -0
  40. ciaf_core-0.1.1/validation_helpers/__init__.py +218 -0
  41. ciaf_core-0.1.1/version.py +4 -0
@@ -0,0 +1,131 @@
1
+ # Changelog
2
+
3
+ All notable changes to the CIAF Core package will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2026-03-21
9
+
10
+ ### Added
11
+
12
+ #### Core Package Structure
13
+ - Initial package structure with `ciaf_core` namespace
14
+ - Package configuration with `pyproject.toml`
15
+ - Business Source License 1.1 (converts to Apache 2.0 on January 1, 2029)
16
+ - Comprehensive README and QUICKSTART documentation
17
+
18
+ #### Schema Models
19
+ - `CIAFEvent` - Canonical event schema
20
+ - `Actor` - Entity performing actions
21
+ - `Subject` - Target of actions
22
+ - `Resource` - Resources involved in actions
23
+ - `Action` - Action performed and outcome
24
+ - `PolicyDecision` - Policy evaluation results
25
+ - `RiskAssessment` - Risk analysis records
26
+ - `ExecutionContext` - Runtime environment information
27
+ - `EvidenceRecord` - Cryptographic evidence tracking
28
+ - `LineageInfo` - Provenance and lineage tracking
29
+ - `GovernanceMapping` - Compliance framework mappings
30
+ - `Relationship` - Entity relationships
31
+ - `SignedEvent` - Cryptographically signed event envelope for authentication and integrity
32
+
33
+ #### Enumerations
34
+ - `ActorType` - Types of actors (human, agent, service, model, system)
35
+ - `SubjectType` - Types of subjects (agent, model, dataset, workflow, policy, etc.)
36
+ - `ResourceType` - Types of resources
37
+ - `ActionType` - Types of actions (read, write, execute, deploy, etc.)
38
+ - `ActionOutcome` - Action outcomes (success, blocked, failed, partial, pending)
39
+ - `EventCategory` - Event categories (execution, governance, deployment, etc.)
40
+ - `RiskLevel` - Risk levels (critical, high, medium, low, minimal, none)
41
+ - `PolicyEffect` - Policy effects (allow, deny, require_approval, etc.)
42
+ - `EvidenceType` - Evidence types
43
+ - `LineageType` - Lineage relationship types
44
+ - `RelationshipType` - Entity relationship types
45
+
46
+ #### Utilities
47
+
48
+ **Canonicalization** (`ciaf_core.canonicalization`)
49
+ - `to_canonical_dict()` - Convert models to canonical dictionaries
50
+ - `to_canonical_json()` - Deterministic JSON serialization
51
+ - `dict_to_canonical_json()` - Dictionary canonicalization
52
+
53
+ **Hashing** (`ciaf_core.hashing`)
54
+ - `sha256_hex()` - SHA-256 hashing (hex output)
55
+ - `sha256_bytes()` - SHA-256 hashing (bytes output)
56
+ - `sha512_hex()` - SHA-512 hashing
57
+ - `blake2b_hex()` - BLAKE2b hashing
58
+ - `compute_merkle_leaf()` - Merkle tree leaf hash
59
+ - `compute_merkle_node()` - Merkle tree node hash
60
+
61
+ **ID Generation** (`ciaf_core.IDs`)
62
+ - `new_event_id()` - Event ID generation
63
+ - `new_entity_id()` - Entity ID generation
64
+ - `new_uuid()` - UUID v4 generation
65
+ - `new_ulid()` - ULID-like ID generation
66
+ - `new_short_id()` - Short random IDs
67
+ - `new_correlation_id()` - Correlation IDs for tracing
68
+ - `new_decision_id()` - Policy decision IDs
69
+ - `new_assessment_id()` - Risk assessment IDs
70
+
71
+ **Validation Helpers** (`ciaf_core.validation_helpers`)
72
+ - `validate_model()` - Pydantic model validation
73
+ - `validate_event_id()` - Event ID format validation
74
+ - `validate_hash()` - Hash string validation
75
+ - `validate_tenant_id()` - Tenant ID validation
76
+ - `is_valid_schema_version()` - Semantic version validation
77
+ - `validate_json_dict()` - JSON dictionary validation
78
+ - `validate_required_fields()` - Required field checking
79
+ - `sanitize_string()` - String sanitization
80
+ - `ensure_dict_keys_valid()` - Dictionary key validation
81
+
82
+ **Signing** (`ciaf_core.signing`)
83
+ - `generate_rsa_keypair()` - Generate RSA key pairs (2048, 3072, or 4096 bit)
84
+ - `generate_ed25519_keypair()` - Generate Ed25519 key pairs (recommended)
85
+ - `generate_ecdsa_keypair()` - Generate ECDSA P-256 key pairs
86
+ - `sign_payload()` - Sign a payload with a private key
87
+ - `verify_signature()` - Verify a signature with a public key
88
+ - `compute_payload_hash()` - Compute SHA-256 hash of payload
89
+ - Support for Ed25519, RSA-PSS-SHA256, and ECDSA-P256-SHA256 algorithms
90
+
91
+ **Builders** (`ciaf_core.builders`)
92
+ - `build_agent_tool_call_event()` - Agent tool call events
93
+ - `build_model_deployment_event()` - Model deployment events
94
+ - `build_policy_decision_event()` - Policy decision events
95
+ - `build_evidence_record()` - Evidence records
96
+ - `build_access_event()` - Resource access events
97
+
98
+ #### Exceptions
99
+ - `CIAFError` - Base exception
100
+ - `CIAFValidationError` - Validation errors
101
+ - `CIAFSchemaError` - Schema errors
102
+ - `CIAFHashError` - Hashing errors
103
+ - `CIAFCanonializationError` - Canonicalization errors
104
+ - `CIAFIDGenerationError` - ID generation errors
105
+ - `CIAFSigningError` - Signing operation errors
106
+ - `CIAFVerificationError` - Signature verification errors
107
+
108
+ #### Testing
109
+ - Comprehensive test suite with pytest
110
+ - Tests for event models
111
+ - Tests for canonicalization
112
+ - Tests for hashing utilities
113
+ - Tests for ID generation
114
+ - Tests for builders
115
+ - Tests for validation helpers
116
+ - Test fixtures and utilities
117
+
118
+ #### Documentation
119
+ - README.md with overview and features
120
+ - QUICKSTART.md with usage examples
121
+ - CHANGELOG.md with release notes
122
+ - Example script (`example_signed_event.py`)
123
+ - Inline code documentation and type hints
124
+
125
+ ### Technical Details
126
+ - Python 3.11+ support
127
+ - Pydantic v2 for data validation
128
+ - Deterministic JSON serialization for cryptographic consistency
129
+ - Schema version 1.0.0 embedded in all events
130
+
131
+ [0.1.0]: https://github.com/your-org/ciaf_core/releases/tag/v0.1.0
@@ -0,0 +1,287 @@
1
+ # Contributing to CIAF Core
2
+
3
+ Thank you for your interest in contributing to CIAF Core! This document provides guidelines for developers.
4
+
5
+ ## Development Setup
6
+
7
+ ### Prerequisites
8
+
9
+ - Python 3.11 or higher
10
+ - Git
11
+ - pip
12
+
13
+ ### Initial Setup
14
+
15
+ 1. **Clone the repository:**
16
+ ```bash
17
+ git clone https://github.com/DenzilGreenwood/ciaf_core.git
18
+ cd ciaf_core
19
+ ```
20
+
21
+ 2. **Create a virtual environment:**
22
+ ```bash
23
+ python -m venv venv
24
+ source venv/bin/activate # On Windows: venv\Scripts\activate
25
+ ```
26
+
27
+ 3. **Install development dependencies:**
28
+ ```bash
29
+ pip install -e .[dev]
30
+ ```
31
+
32
+ ## Development Workflow
33
+
34
+ ### Running Tests
35
+
36
+ ```bash
37
+ # Run all tests
38
+ pytest tests/ -p no:asyncio
39
+
40
+ # Run with coverage
41
+ pytest tests/ -p no:asyncio --cov=ciaf_core --cov-report=html
42
+
43
+ # Run specific test file
44
+ pytest tests/test_signing.py -p no:asyncio -v
45
+ ```
46
+
47
+ ### Code Quality
48
+
49
+ ```bash
50
+ # Format code with black
51
+ black ciaf_core tests
52
+
53
+ # Lint with ruff
54
+ ruff check ciaf_core tests
55
+ ```
56
+
57
+ ### Building the Package
58
+
59
+ ```bash
60
+ # Clean previous builds
61
+ Remove-Item -Recurse -Force dist, build, *.egg-info -ErrorAction SilentlyContinue
62
+
63
+ # Build distribution
64
+ python -m build
65
+
66
+ # Verify package
67
+ python -m twine check dist/*
68
+ ```
69
+
70
+ ## Code Guidelines
71
+
72
+ ### Python Style
73
+
74
+ - Follow PEP 8 style guidelines
75
+ - Use type hints for all function parameters and return values
76
+ - Document all public APIs with docstrings
77
+ - Keep line length to 100 characters (configured in pyproject.toml)
78
+
79
+ ### Schema Design
80
+
81
+ When adding or modifying schemas:
82
+
83
+ 1. **Backward Compatibility**: Ensure changes don't break existing code
84
+ 2. **Validation**: Use Pydantic validators for data integrity
85
+ 3. **Documentation**: Add clear docstrings explaining the schema purpose
86
+ 4. **Tests**: Include comprehensive tests for new schemas
87
+
88
+ Example:
89
+ ```python
90
+ from pydantic import BaseModel, Field, ConfigDict
91
+
92
+ class MySchema(BaseModel):
93
+ """
94
+ Brief description of what this schema represents.
95
+
96
+ Used for: Explain the use case
97
+ """
98
+
99
+ model_config = ConfigDict(
100
+ extra="forbid",
101
+ str_strip_whitespace=True,
102
+ )
103
+
104
+ field_name: str = Field(
105
+ ...,
106
+ description="Clear description of the field",
107
+ min_length=1,
108
+ )
109
+ ```
110
+
111
+ ### Utility Functions
112
+
113
+ - Keep functions focused on a single responsibility
114
+ - Add error handling with custom exceptions
115
+ - Include usage examples in docstrings
116
+ - Write tests covering both success and error cases
117
+
118
+ ### Enumeration Guidelines
119
+
120
+ - Use descriptive names in UPPER_SNAKE_CASE
121
+ - Provide clear enum class docstrings
122
+ - String values should be lowercase with hyphens
123
+ - Add new enum values only at the end (for backward compatibility)
124
+
125
+ ## Testing Guidelines
126
+
127
+ ### Test Structure
128
+
129
+ ```python
130
+ def test_feature_name():
131
+ """Test description explaining what is being tested."""
132
+ # Arrange: Set up test data
133
+ input_data = {...}
134
+
135
+ # Act: Execute the function
136
+ result = function_under_test(input_data)
137
+
138
+ # Assert: Verify the result
139
+ assert result.field == expected_value
140
+ ```
141
+
142
+ ### Test Coverage
143
+
144
+ - Aim for 90%+ code coverage
145
+ - Test both success and failure paths
146
+ - Include edge cases and boundary conditions
147
+ - Test error handling and validation
148
+
149
+ ### Test Fixtures
150
+
151
+ Use pytest fixtures for reusable test data:
152
+
153
+ ```python
154
+ @pytest.fixture
155
+ def sample_event():
156
+ """Fixture providing a sample CIAF event."""
157
+ return CIAFEvent(...)
158
+ ```
159
+
160
+ ## Commit Guidelines
161
+
162
+ ### Commit Messages
163
+
164
+ Follow conventional commit format:
165
+
166
+ ```
167
+ type(scope): brief description
168
+
169
+ Longer explanation if needed
170
+
171
+ Fixes #issue-number
172
+ ```
173
+
174
+ **Types:**
175
+ - `feat`: New feature
176
+ - `fix`: Bug fix
177
+ - `docs`: Documentation changes
178
+ - `test`: Test additions or changes
179
+ - `refactor`: Code refactoring
180
+ - `chore`: Build/tooling changes
181
+
182
+ **Examples:**
183
+ ```
184
+ feat(signing): add ECDSA P-256 signature support
185
+
186
+ Add support for ECDSA P-256 signatures alongside Ed25519 and RSA.
187
+ Includes key generation, signing, and verification functions.
188
+
189
+ Fixes #42
190
+ ```
191
+
192
+ ## Pull Request Process
193
+
194
+ 1. **Create a branch:**
195
+ ```bash
196
+ git checkout -b feature/my-new-feature
197
+ ```
198
+
199
+ 2. **Make changes and commit:**
200
+ ```bash
201
+ git add .
202
+ git commit -m "feat(scope): description"
203
+ ```
204
+
205
+ 3. **Run tests and ensure they pass:**
206
+ ```bash
207
+ pytest tests/ -p no:asyncio
208
+ ```
209
+
210
+ 4. **Push to GitHub:**
211
+ ```bash
212
+ git push origin feature/my-new-feature
213
+ ```
214
+
215
+ 5. **Create Pull Request:**
216
+ - Provide clear description of changes
217
+ - Reference any related issues
218
+ - Ensure CI/CD checks pass
219
+ - Wait for review
220
+
221
+ ## Versioning
222
+
223
+ This package follows [Semantic Versioning](https://semver.org/):
224
+
225
+ - **MAJOR**: Breaking changes
226
+ - **MINOR**: New features (backward compatible)
227
+ - **PATCH**: Bug fixes
228
+
229
+ ### Version Updates
230
+
231
+ When incrementing version:
232
+
233
+ 1. Update `version` in `pyproject.toml`
234
+ 2. Update `CHANGELOG.md` with changes
235
+ 3. Create a git tag: `git tag v0.2.0`
236
+ 4. Push tag: `git push origin v0.2.0`
237
+
238
+ ## Documentation
239
+
240
+ ### Docstring Format
241
+
242
+ Use Google-style docstrings:
243
+
244
+ ```python
245
+ def my_function(param1: str, param2: int) -> bool:
246
+ """
247
+ Brief one-line description.
248
+
249
+ Longer description explaining the function purpose,
250
+ behavior, and usage.
251
+
252
+ Args:
253
+ param1: Description of param1
254
+ param2: Description of param2
255
+
256
+ Returns:
257
+ Description of return value
258
+
259
+ Raises:
260
+ ValueError: When validation fails
261
+
262
+ Example:
263
+ >>> result = my_function("test", 42)
264
+ >>> assert result is True
265
+ """
266
+ ```
267
+
268
+ ### Updating Documentation
269
+
270
+ When adding features:
271
+
272
+ 1. Update README.md with new capabilities
273
+ 2. Add examples to QUICKSTART.md
274
+ 3. Update CHANGELOG.md under "Unreleased"
275
+ 4. Create or update example scripts
276
+
277
+ ## License
278
+
279
+ By contributing to CIAF Core, you agree that your contributions will be licensed under the Business Source License 1.1 (BUSL-1.1).
280
+
281
+ ## Questions?
282
+
283
+ - **Repository**: https://github.com/DenzilGreenwood/ciaf_core
284
+ - **Issues**: https://github.com/DenzilGreenwood/ciaf_core/issues
285
+ - **Email**: Founder@CognitiveInsight.ai
286
+
287
+ Thank you for contributing to CIAF Core!
@@ -0,0 +1,192 @@
1
+ """
2
+ ID generation and management utilities for CIAF Core.
3
+
4
+ Provides functions for generating unique identifiers for events and entities.
5
+ """
6
+
7
+ import uuid
8
+ import secrets
9
+ from datetime import datetime, timezone
10
+ from ..exceptions import CIAFIDGenerationError
11
+
12
+
13
+ def new_event_id(prefix: str = "evt") -> str:
14
+ """
15
+ Generate a new unique event ID.
16
+
17
+ Format: {prefix}_{timestamp}_{random}
18
+ Example: evt_20240321_abc123xyz
19
+
20
+ Args:
21
+ prefix: Prefix for the event ID (default: "evt")
22
+
23
+ Returns:
24
+ Unique event ID string
25
+
26
+ Raises:
27
+ CIAFIDGenerationError: If ID generation fails
28
+ """
29
+ try:
30
+ timestamp = datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S")
31
+ random_suffix = secrets.token_hex(8) # 16 characters
32
+ return f"{prefix}_{timestamp}_{random_suffix}"
33
+ except Exception as e:
34
+ raise CIAFIDGenerationError(f"Failed to generate event ID: {e}") from e
35
+
36
+
37
+ def new_entity_id(entity_type: str, prefix: str = "") -> str:
38
+ """
39
+ Generate a new unique entity ID.
40
+
41
+ Format: {prefix}{entity_type}_{uuid}
42
+ Example: agent_550e8400-e29b-41d4-a716-446655440000
43
+
44
+ Args:
45
+ entity_type: Type of entity (e.g., "agent", "model", "policy")
46
+ prefix: Optional prefix (default: "")
47
+
48
+ Returns:
49
+ Unique entity ID string
50
+
51
+ Raises:
52
+ CIAFIDGenerationError: If ID generation fails
53
+ """
54
+ try:
55
+ unique_id = str(uuid.uuid4())
56
+ if prefix:
57
+ return f"{prefix}{entity_type}_{unique_id}"
58
+ return f"{entity_type}_{unique_id}"
59
+ except Exception as e:
60
+ raise CIAFIDGenerationError(f"Failed to generate entity ID: {e}") from e
61
+
62
+
63
+ def new_uuid() -> str:
64
+ """
65
+ Generate a new UUID v4.
66
+
67
+ Returns:
68
+ UUID string (e.g., "550e8400-e29b-41d4-a716-446655440000")
69
+
70
+ Raises:
71
+ CIAFIDGenerationError: If UUID generation fails
72
+ """
73
+ try:
74
+ return str(uuid.uuid4())
75
+ except Exception as e:
76
+ raise CIAFIDGenerationError(f"Failed to generate UUID: {e}") from e
77
+
78
+
79
+ def new_ulid() -> str:
80
+ """
81
+ Generate a new ULID (Universally Unique Lexicographically Sortable Identifier).
82
+
83
+ Note: This is a simplified implementation. For production use, consider
84
+ installing the 'python-ulid' package for full ULID support.
85
+
86
+ Returns:
87
+ ULID-like string based on timestamp and randomness
88
+
89
+ Raises:
90
+ CIAFIDGenerationError: If ULID generation fails
91
+ """
92
+ try:
93
+ # Simplified ULID: timestamp in milliseconds + random bytes
94
+ timestamp_ms = int(datetime.now(timezone.utc).timestamp() * 1000)
95
+ random_part = secrets.token_hex(10) # 20 characters
96
+ return f"{timestamp_ms:013x}{random_part}"
97
+ except Exception as e:
98
+ raise CIAFIDGenerationError(f"Failed to generate ULID: {e}") from e
99
+
100
+
101
+ def new_short_id(length: int = 12) -> str:
102
+ """
103
+ Generate a short random ID.
104
+
105
+ Useful for correlation IDs, request IDs, etc.
106
+
107
+ Args:
108
+ length: Length of the ID in characters (default: 12)
109
+
110
+ Returns:
111
+ Random hexadecimal ID string
112
+
113
+ Raises:
114
+ CIAFIDGenerationError: If ID generation fails
115
+ """
116
+ try:
117
+ if length < 4:
118
+ raise ValueError("Length must be at least 4 characters")
119
+ byte_length = (length + 1) // 2
120
+ return secrets.token_hex(byte_length)[:length]
121
+ except Exception as e:
122
+ raise CIAFIDGenerationError(f"Failed to generate short ID: {e}") from e
123
+
124
+
125
+ def new_correlation_id() -> str:
126
+ """
127
+ Generate a new correlation ID for tracing across systems.
128
+
129
+ Returns:
130
+ Correlation ID string
131
+
132
+ Raises:
133
+ CIAFIDGenerationError: If correlation ID generation fails
134
+ """
135
+ try:
136
+ return f"corr_{new_short_id(16)}"
137
+ except Exception as e:
138
+ raise CIAFIDGenerationError(f"Failed to generate correlation ID: {e}") from e
139
+
140
+
141
+ def new_decision_id(prefix: str = "dec") -> str:
142
+ """
143
+ Generate a new unique decision ID.
144
+
145
+ Args:
146
+ prefix: Prefix for the decision ID (default: "dec")
147
+
148
+ Returns:
149
+ Unique decision ID string
150
+
151
+ Raises:
152
+ CIAFIDGenerationError: If decision ID generation fails
153
+ """
154
+ try:
155
+ timestamp = datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S")
156
+ random_suffix = secrets.token_hex(6) # 12 characters
157
+ return f"{prefix}_{timestamp}_{random_suffix}"
158
+ except Exception as e:
159
+ raise CIAFIDGenerationError(f"Failed to generate decision ID: {e}") from e
160
+
161
+
162
+ def new_assessment_id(prefix: str = "assess") -> str:
163
+ """
164
+ Generate a new unique assessment ID.
165
+
166
+ Args:
167
+ prefix: Prefix for the assessment ID (default: "assess")
168
+
169
+ Returns:
170
+ Unique assessment ID string
171
+
172
+ Raises:
173
+ CIAFIDGenerationError: If assessment ID generation fails
174
+ """
175
+ try:
176
+ timestamp = datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S")
177
+ random_suffix = secrets.token_hex(6) # 12 characters
178
+ return f"{prefix}_{timestamp}_{random_suffix}"
179
+ except Exception as e:
180
+ raise CIAFIDGenerationError(f"Failed to generate assessment ID: {e}") from e
181
+
182
+
183
+ __all__ = [
184
+ "new_event_id",
185
+ "new_entity_id",
186
+ "new_uuid",
187
+ "new_ulid",
188
+ "new_short_id",
189
+ "new_correlation_id",
190
+ "new_decision_id",
191
+ "new_assessment_id",
192
+ ]