3.0 KiB
3.0 KiB
Road Revision Storage
1. Scope / Trigger
src/compile/road-revisions.js owns the persistent v2 workbench layout. It is called after a successful import and when an existing workbench area is read, so legacy import-* directories migrate lazily without an administrative command.
2. Signatures
ensureRevisionStore(workspace) // -> { paths, active, baseline }
createCheckpoint(workspace, label) // -> restored revision
readRevision(workspace, revisionId) // -> { manifest, osm, nativeRoadOverrides, directEdits, trafficSignals }
3. Contracts
- Legacy inputs remain at
source.osm,native-road-overrides.json, andnative-traffic-signals.json; migration must never rewrite them. - OSM bytes are stored once under
osm/<sha256>.osm. active/native-road-edits.jsonstarts as a validated v2 document at version0;active/state.jsonpoints to the active revision.- A revision is immutable at
revisions/rev-NNNN/. Itsmanifest.jsonusesroad-workbench-revision/v1, references the content-addressed OSM, lists frozen JSON documents, and records SHA-256 digests. - Area-config snapshots are intentionally owned by the subsequent snapshot step. Do not silently fall back to the external config when that step is introduced.
4. Validation And Error Matrix
| Condition | Error / behavior |
|---|---|
| Required legacy input missing | Revision source is missing: <path> |
| Content-addressed OSM differs from its filename digest | Content-addressed OSM is corrupt |
| Revision manifest schema or ID mismatch | Invalid revision manifest |
Revision ID is not rev-NNNN |
Reject with Invalid revision id |
| Manifest path leaves its OSM or revision directory | Reject the read; never resolve an external path |
| Referenced frozen OSM or JSON digest mismatch | Reject the read with a digest mismatch error |
| Empty checkpoint label | Reject with label must be a non-empty string |
5. Good / Base / Bad Cases
- Good: first open of a legacy directory adds
osm/,active/, andrevisions/rev-0001/, leaving old files byte-identical. - Base: opening an already migrated directory is idempotent; an interrupted migration with a baseline but no active state repairs only the missing state file.
- Bad: mutating a frozen revision document or its referenced OSM must make
readRevision()fail rather than returning altered input.
6. Tests Required
test/road-revisions.js must cover:
- legacy-byte preservation and baseline creation;
- equal OSM bytes yielding one content-addressed copy;
- named checkpoint creation, parent linkage, and complete restore;
- manifest digest equality with the actual frozen files;
- invalid checkpoint labels.
7. Wrong Vs Correct
Wrong
fs.copyFileSync(sourceOsm, path.join(revisionDirectory, 'source.osm'));
This duplicates equal OSM files and provides no integrity check.
Correct
const { file, digest } = storeOsm(paths);
manifest.source = { osmFile: path.relative(paths.workspace, file), osmSha256: digest };
The content address is both the deduplication key and the integrity contract.