Source Hash and Validation Systems for CAD Artifacts in Text‑to‑CAD
The Text‑to‑CAD repository implements a dual-layer integrity system that computes SHA‑256 source hashes for every CAD file and validates them against embedded metadata to detect stale artifacts and schema mismatches.
The earthtojake/text-to-cad project treats every generated artifact—from STEP and STL to GLB and URDF—as a versioned, verifiable object. Understanding the source hash and validation systems for CAD artifacts is essential for maintaining consistency across the generation pipeline and ensuring that downstream consumers always receive current, uncorrupted geometry.
How Source Hashes Work
The source hash is a deterministic SHA‑256 fingerprint of the original file embedded directly into artifact metadata. This allows the system to detect when a generated GLB or other derived format no longer matches its underlying source.
Computing the Hash
The utility function sha256File() in viewer/src/server/catalog/cadDirectoryScanner.mjs (lines 45‑61) streams the file and produces a 64‑character hexadecimal hash:
import { sha256File } from 'viewer/src/server/catalog/cadDirectoryScanner.mjs';
const hash = await sha256File('/models/parts/bracket.step');
// Returns: 'a3f5c8...64 chars...'
Embedding Hash Metadata
During GLB generation, the hash is written to the GLB extension under manifest.sourceHash. The Python generator in packages/cadpy_metadata/src/cadpy_metadata/generator.py populates this field from comment metadata (<!-- cadpy:sourceHash=… -->), while the Node.js compiler in viewer/src/server/step/stepArtifactCompiler.mjs orchestrates the injection:
// From stepArtifactCompiler.mjs
const metadata = {
sourcePath: relativeSourcePath,
sourceHash: await sha256File(sourcePath),
stepHash: await sha256File(stepPath)
};
Reading Stored Hashes
The validateStepTopologyArtifact() function extracts the stored hash from manifest.sourceHash and recomputes the current hash of the underlying STEP file (currentStepHash) for comparison.
The Validation Pipeline
The validation system enforces a strict sequence of checks that return structured results containing ok, error, hash, sourceKind, and other metadata. Any failure returns a machine‑readable error code and human‑readable message.
Step‑by‑Step Validation Sequence
- Locate the artifact –
inlineStepGlbArtifactPathForSource(sourcePath)builds the path to the inline GLB. - Check existence – Returns
missing_glbif the file is absent. - Parse the container –
readGlbTopologyContainer()(lines 105‑155) verifies the GLB header and extracts the JSON chunk. - Validate STEP topology extension – Checks for
STEP_topologyextension (missing_step_topology) and correct schema version (STEP_TOPOLOGY_SCHEMA_VERSION, returnsunsupported_step_topologyif mismatched). - Validate source identity – Verifies
sourcePathexists in manifest (missing_source_pathif absent). - Validate hash consistency – Compares stored
stepHashagainst freshly computed SHA‑256 of the STEP file, returningstale_step_artifacton mismatch ormissing_step_hashif the field is absent. - Validate topology views – Ensures edge topology (
STEP_EDGE_BARYCENTRIC_ATTRIBUTE,STEP_EDGE_CLASS_ATTRIBUTE) and selector views conform to schema, returningmissing_edge_topologyormissing_selector_topologyif required attributes are absent.
Validation Result Structure
On success, validateStepTopologyArtifact() returns:
{
topology, // parsed STEP topology description
stepArtifact: {
ok: true,
sourceKind,
sourcePath,
glbPath,
...
},
glbPath,
stepHash,
sourceHash,
}
On failure, stepArtifact.ok is false and includes a detailed error object with code and message.
Key Implementation Files
| File | Role |
|---|---|
viewer/src/server/catalog/cadDirectoryScanner.mjs |
Implements sha256File, validateStepTopologyArtifact, and readStepSourceStatus |
viewer/src/server/step/stepArtifactCompiler.mjs |
Orchestrates GLB generation and metadata injection |
viewer/src/server/step/stepMetadata.mjs |
Parses CAD‑specific comment metadata (<!-- cadpy:sourceHash=… -->) |
packages/cadpy_metadata/src/cadpy_metadata/generator.py |
Python‑side hash computation and GLB manifest population |
viewer/src/client/workbench/fileStatusItems.js |
Maps validation error codes to UI messages |
Practical Usage Examples
Validate a STEP File Programmatically
Use validateStepTopologyArtifact() to verify a generated GLB matches its source:
import { validateStepTopologyArtifact } from
'viewer/src/server/catalog/cadDirectoryScanner.mjs';
const result = validateStepTopologyArtifact({
repoRoot: '/path/to/repo',
sourcePath: '/models/parts/bracket.step',
cadPath: 'parts/bracket.step'
});
if (result.stepArtifact.ok) {
console.log('✅ GLB is up‑to‑date');
} else {
console.error('❌ Validation failed:', result.stepArtifact.error);
}
Inspect Embedded Source Hashes
Extract the sourceHash from a generated GLB:
import { readStepCatalogMetadata } from
'viewer/src/server/catalog/cadDirectoryScanner.mjs';
const meta = readStepCatalogMetadata({
repoRoot: '/path/to/repo',
glbPath: '/models/parts/.bracket.step.glb'
});
console.log('Source hash:', meta.sourceHash);
Python Generator Integration
Embed hashes when generating artifacts:
# packages/cadpy_metadata/src/cadpy_metadata/generator.py
def generate_step(source_path: Path, output_glb: Path):
# ... generate geometry ...
metadata = {
"sourcePath": str(source_path.relative_to(repo_root)),
"sourceHash": compute_sha256(source_path),
"stepHash": compute_sha256(step_file),
}
embed_metadata_into_glb(output_glb, metadata)
Summary
- Source hashes are SHA‑256 fingerprints computed by
sha256File()and embedded in GLB metadata undermanifest.sourceHash. - Validation occurs through
validateStepTopologyArtifact(), which checks file existence, schema versions (STEP_TOPOLOGY_SCHEMA_VERSION), hash consistency, and required topology attributes. - Error codes like
stale_step_artifactandmissing_step_hashprovide precise diagnostics for CI/CD pipelines and viewer UIs. - The system spans both Node.js (
cadDirectoryScanner.mjs,stepArtifactCompiler.mjs) and Python (generator.py) to ensure end‑to‑end integrity.
Frequently Asked Questions
What happens when a STEP file changes but the GLB is not regenerated?
The validator returns a stale_step_artifact error because the stored stepHash in the GLB metadata no longer matches the recomputed SHA‑256 of the current STEP file. This prevents downstream tools from using outdated geometry.
Where is the source hash actually stored inside a GLB file?
According to viewer/src/server/step/stepArtifactCompiler.mjs, the hash is written to the GLB’s JSON chunk under the extension key manifest.sourceHash. Python‑generated artifacts insert this via the cadpy_metadata package as a comment that gets parsed into the same structure.
Can I validate artifacts without loading the full GLB into memory?
Yes. Use readStepSourceStatus() in viewer/src/server/catalog/cadDirectoryScanner.mjs, which provides a lightweight wrapper around the validation logic suitable for quick checks in CLI tools and file watchers.
What error code indicates a schema version mismatch?
If the GLB’s STEP_topology extension exists but uses an outdated schema version, the validator returns unsupported_step_topology. The expected version is defined by the constant STEP_TOPOLOGY_SCHEMA_VERSION in the scanner module.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →