TWPack Format
TWPack (Traceability Workload Pack) is a deterministic ZIP archive that packages traceability evidence. Every file inside follows a documented schema so tooling can validate, stream, and transform data without bespoke adapters.
Archive Layout
example.twpack
├── manifest.json # Package metadata and schema references
├── artifacts.jsonl # Artifact definitions (one JSON object per line)
├── links.jsonl # Traceability relationships between artifacts
├── signatures.json # Cryptographic signatures and provenance
├── metadata.json # Optional package-level context
└── attachments/ # Binary evidence linked from artifacts
Core Files
| File | Purpose | Key fields |
|---|---|---|
manifest.json | Describes the package, generator, and included domains. | twpack_version, schema_version, created, created_by, domains, artifact_count, link_count, content_hash, generator |
artifacts.jsonl | Declares artifacts such as requirements, tests, models, hazards. | id, type, title, domain-specific attributes, created, hash |
links.jsonl | Expresses relationships across artifacts. | from, to, type, created, optional confidence |
signatures.json | Captures package and artifact signatures. | signature algorithm, signer metadata, timestamps |
metadata.json | Stores optional package-level attributes. | free-form JSON used by profiles or integrations |
Sample manifest.json:
{
"twpack_version": "2.0.0",
"schema_version": "2.0.0",
"created": "2024-01-20T15:30:00Z",
"created_by": "build-system@example.com",
"domains": ["automotive", "ai_ml"],
"artifact_count": 1247,
"link_count": 2834,
"content_hash": "sha256:a1b2c3d4e5f6...",
"generator": {
"name": "tw-cli",
"version": "2.0.1",
"platform": "linux-x64"
}
}
Sample entries from artifacts.jsonl:
{"id": "req:REQ-001", "type": "requirement", "title": "System shall detect obstacles", "content": "Detect obstacles within 100m with 99.9% accuracy", "created": "2024-01-15T10:30:00Z", "hash": "sha256:a1b2c3..."}
{"id": "test:TC-001", "type": "test", "title": "Obstacle detection", "status": "passed", "procedure": "Execute automated suite", "results": {"success": true, "coverage": 0.95}, "created": "2024-01-20T14:45:00Z", "hash": "sha256:d4e5f6..."}
{"id": "model:OD-v2.1", "type": "model", "title": "Obstacle detection neural network", "framework": "pytorch", "accuracy": 0.999, "training_data": "dataset:KITTI-2024", "created": "2024-01-18T09:15:00Z", "hash": "sha256:g7h8i9..."}
{"id": "hazard:H-001", "type": "hazard", "title": "Undetected obstacle", "severity": "catastrophic", "asil_level": "D", "created": "2024-01-10T08:00:00Z", "hash": "sha256:j1k2l3..."}
Sample entries from links.jsonl:
{"from": "req:REQ-001", "to": "test:TC-001", "type": "tested_by", "created": "2024-01-20T14:45:00Z", "confidence": 1.0}
{"from": "req:REQ-001", "to": "model:OD-v2.1", "type": "implemented_by", "created": "2024-01-18T09:15:00Z", "confidence": 0.95}
{"from": "hazard:H-001", "to": "req:REQ-001", "type": "mitigated_by", "created": "2024-01-15T10:30:00Z", "confidence": 1.0}
{"from": "model:OD-v2.1", "to": "test:TC-001", "type": "validated_by", "created": "2024-01-20T14:45:00Z", "confidence": 0.98}
signatures.json optionally enumerates package, artifact, and witness signatures:
{
"package_signature": {
"algorithm": "RSA-SHA256",
"signature": "base64-encoded-signature",
"certificate": "X.509-certificate-chain",
"timestamp": "2024-01-20T15:30:00Z",
"signer": "build-system@example.com"
},
"artifact_signatures": [
{
"artifact_id": "req:REQ-001",
"hash": "sha256:a1b2c3d4e5f6...",
"signature": "base64-encoded-signature",
"signer": "requirements-team@example.com",
"timestamp": "2024-01-15T10:30:00Z"
}
],
"witness_signatures": [
{
"witness": "quality-assurance@example.com",
"signature": "base64-encoded-signature",
"timestamp": "2024-01-20T16:00:00Z",
"scope": "complete_package"
}
]
}
Identifiers and Attachments
- Artifact identifiers follow
namespace:identifier(e.g.,req:FUNC-001,test:UNIT-TC-042,model:perception-v2.1,hazard:H-STEERING-01). - Timestamps use ISO 8601 UTC (
YYYY-MM-DDTHH:MM:SSZ, e.g.,2024-01-20T15:30:00Z). - Hashes are SHA-256 with hex encoding (
sha256:a1b2...).
Large binaries reside inside attachments/ and are referenced via relative paths:
{
"id": "design:ARCH-001",
"type": "design",
"title": "System architecture diagram",
"attachments": [
{
"filename": "architecture.png",
"path": "attachments/design-diagrams/architecture.png",
"size": 1048576,
"mime_type": "image/png",
"hash": "sha256:b2c3d4e5f6..."
}
]
}
Artifacts can link directly to reports stored in attachments:
{
"id": "test:RESULTS-001",
"type": "test",
"title": "Integration test results",
"results_file": "attachments/test-results.xml",
"coverage_report": "attachments/coverage-report.html"
}
Deterministic Packaging
- Sorted output: artifacts and links are serialized in identifier order.
- Normalized timestamps: UTC with consistent precision.
- Standard compression settings for reproducible ZIPs.
- Stable hashing: archived content hashed from normalized data.
Determinism allows treating TWPack files like source code:
git add evidence/sprint-1.twpack
git commit -m "Add sprint 1 evidence package"
git diff --binary evidence/sprint-1.twpack
git lfs track "*.twpack"
Validation Workflow
All JSON payloads are validated against versioned schemas:
{
"artifact_schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["id", "type", "title", "created", "hash"],
"properties": {
"id": {"type": "string", "pattern": "^[a-z_]+:[A-Za-z0-9_-]+$"},
"type": {"type": "string", "enum": ["requirement", "test", "design", "component"]},
"hash": {"type": "string", "pattern": "^sha256:[a-f0-9]{64}$"}
}
}
}
Validation commands:
tw validate package.twpack --check-structure
tw validate package.twpack --check-hashes
tw validate package.twpack --check-schemas
tw validate package.twpack --check-signatures
Streaming and Integration
JSONL enables streaming analysis without loading an entire package into memory:
def process_large_twpack(twpack_path):
with TWPackReader(twpack_path) as reader:
for artifact in reader.stream_artifacts():
yield process_artifact(artifact)
Domain-specific processing can run in parallel:
def parallel_domain_analysis(twpack_path):
artifacts_by_domain = defaultdict(list)
with TWPackReader(twpack_path) as reader:
for artifact in reader.stream_artifacts():
domain = get_artifact_domain(artifact.type)
artifacts_by_domain[domain].append(artifact)
with ProcessPoolExecutor() as executor:
results = executor.map(analyze_domain, artifacts_by_domain.values())
return combine_results(results)
Typical import flows:
tw import jira_export.xml --output requirements.twpack
tw import testlink_results.json --output test_evidence.twpack
tw import mlflow_experiment.json --output ml_models.twpack
Typical export flows:
tw export evidence.twpack --format iso26262 --output safety_case.pdf
tw export evidence.twpack --format csv --output traceability_matrix.csv
tw export evidence.twpack --format graphml --output dependency_graph.xml
Standardization keeps integrations predictable and ensures every stakeholder can exchange traceability data without bespoke conversions.