After every guarded install orDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/CarlosEduJs/SCAL-P/llms.txt
Use this file to discover all available pages before exploring further.
scalp ci run, SCAL-P hashes each package directory in node_modules using SHA-512 and stores the results in .scalp/lockfile.json. On subsequent scalp audit or scalp ci runs it re-hashes the same directories and compares the results against the stored entries, detecting any modifications made after installation. Do not commit this file to version control — it is local state that must reflect the actual on-disk packages.
File structure
The lockfile is a JSON object with three top-level fields, as defined ininternal/lockfile/lockfile.go:
Internal schema version. Always
1 in the current release.RFC 3339 UTC timestamp of the last write. Updated every time
SyncWithTree completes.A map of
"name@version" keys to lock entries. Keys use the exact package name and resolved version, for example "lodash@4.17.21".Example
How the lockfile is generated
SCAL-P generates the lockfile throughSyncWithTree() in internal/lockfile/sync.go. The process runs at the end of every guarded install and at the hash-sync step of scalp ci:
- Flatten the dependency tree —
pkgmanager.Flatten(tree)turns the nested tree returned bynpm lsorpnpm lsinto a flat list ofPackageNoderecords. - Locate each package directory — SCAL-P checks the path reported by the package manager first, then falls back to
node_modules/<name>. For pnpm, symlinks are resolved to their real paths before hashing, becausehash.Diroperates on real directories. - Hash the directory —
hash.Dir(ctx, pkgDir)computes a SHA-512 digest over every file in the package directory. The result is stored assha512-<base64>. - Write the entry — The
packages["name@version"]entry is updated withresolved,integrity, andverifiedAt. - Save atomically — The file is written atomically using a temp-file rename to prevent partial writes.
hash_skipped audit event and are omitted from the lockfile for that run.
How the lockfile is used
Audit verification
scalp audit and the verification step of scalp ci call VerifyAgainstTree(). For each package in the current dependency tree, SCAL-P re-hashes the directory and compares the result against the stored integrity field:
- Match →
hash_checkevent withstatus: "verified"andhash_match: true. - Mismatch →
hash_checkevent withstatus: "mismatch", plus ahash_mismatchviolation. This indicates the package was modified after install — either tampered with or corrupted. - Package not in lockfile →
hash_missingevent and amissing_lock_entryviolation. This means the package was installed outside of SCAL-P’s guarded flow. - Package not installed →
hash_checkevent withstatus: "missing"and apackage_not_installedviolation.
Trust scoring
Whentrust.min_score is greater than 0, the trust scorer checks whether each package has a non-empty integrity entry in the lockfile. If it does, the package earns 30 points (the hash-verified factor). If the entry is missing or empty, it earns 0 points for that factor. When trust.require_hash is also true, a missing entry is an immediate violation regardless of the total score.
What triggers regeneration
The lockfile is updated in two situations:scalp install --guarded— After a successful install,SyncWithTreere-hashes all packages and overwrites existing entries with fresh values.scalp ci— After the install step,SyncWithTreeis always called. This ensures the lockfile reflects the exact state installed in the CI environment.
scalp install without --guarded still calls SyncWithTree and updates the lockfile — it just skips the pre-install policy evaluation.
How to regenerate
If you need to rebuild the lockfile from scratch (for example after deleting it or after a clean install):SyncWithTree at the end and write a fresh .scalp/lockfile.json.
The lockfile is not a replacement for
package-lock.json or pnpm-lock.yaml. Those files pin exact package versions for reproducible installs. The SCAL-P lockfile stores content hashes to verify that installed packages match what was hashed at install time.