Lock Command¶
The lock command walks every dependency in fastc.toml, fetches it into
the shared cache, computes its content sha256, and writes the result into
fastc.lock. It's the verifier's source of truth.
Think of it as cargo update with content-hash verification: every dep is
anchored against the exact bytes that were fetched, and every subsequent
build cross-checks against that anchor.
Usage¶
Options¶
| Option | Description |
|---|---|
--force |
Re-hash every dependency and overwrite the recorded sha256, even if no manifest entry changed. Use after an upstream rewrites a rev (force-push) and you've decided the new contents are safe. |
-h, --help |
Print help |
Behavior¶
For each git dep in fastc.toml:
- Fetch. No-op if the dep is already in the shared cache.
- Hash. Walks the tree (sans
.git/) and computes a lowercase hex sha256. - Verify or write. If
fastc.lockalready has a sha256 for this dep and--forceis not set, the computed value is compared to the recorded one. A match printsunchanged: <short-hash>and moves on. A mismatch aborts the wholelockoperation with an error pointing at the offending dep — that's the alarm bell for an upstream tree changing under you. - Record. With
--force, or when the dep wasn't previously locked, the new sha256 is written intofastc.lock.
Path deps ({ path = "..." }) are skipped — there's no upstream to attest
to, and the build verifies them by recompilation instead.
The fastc.lock Schema¶
# This file is auto-generated by fastc. Do not edit.
# Commit this file to version control for reproducible builds.
[[package]]
name = "fastc-core-cli"
version = "0.1.0"
source = "git+https://github.com/Skelf-Research/fastc-core-cli?rev=<commit-sha>"
resolved = "<commit-sha>"
sha256 = "9b1f3c5e7d2a8b4f6c0e1d2a3b4c5d6e7f8091a2b3c4d5e6f7a8b9c0d1e2f3a4b"
Fields:
| Field | Description |
|---|---|
name |
Dep name as it appears under [dependencies] in fastc.toml. |
version |
The dep's own [package].version, read from its manifest. |
source |
git+<url>?rev=<commit> form. Stable across invocations. |
resolved |
The resolved git commit (40-char SHA), or the rev string if no commit lookup was possible. Omitted when neither is available. |
sha256 |
Content-tree sha256, lowercase hex, recorded at fetch time. |
Entries are sorted alphabetically by name for deterministic output.
The Integrity Story¶
fastc build walks every entry in fastc.lock before compiling:
- Re-hash the cached vendor copy under
.fastc/vendor/<name>/(or the shared cache). - Compare against the recorded
sha256. - Refuse to proceed on mismatch.
No silent stale builds. If a dep's tree no longer matches the locked hash, the build fails loudly and points at the offending dep. The user's choices are to either re-lock (if they intended the change) or audit the diff before approving.
The manifest can also carry a sha256 field; when both manifest and
lockfile record a hash, both must agree. That's the supply-chain
double-check: a malicious actor would need to mutate both files.
Relationship to the Build Cache¶
The build cache key includes a dep_content_hash field — a sha256 derived
from concatenating every locked dep's sha256 in name-sorted order. The
implication:
- Changing a single dep's
rev(and re-runningfastc lock) flips the whole project'sdep_content_hash. - A flipped
dep_content_hashinvalidates every cached C artifact for the project on this machine. - Two checkouts of the same source on different machines with the same
fastc.lockproduce byte-identical C and share cache entries.
See compile.md for the broader build-cache picture.
Worked Example: Green Path¶
A project with one dep:
# fastc.toml
[package]
name = "my-app"
[dependencies]
fastc-core-cli = { git = "https://github.com/Skelf-Research/fastc-core-cli", rev = "v0.1.0", sha256 = "9b1f3c5e..." }
After fastc lock:
Exit code: 0. fastc.lock already had a matching sha256, so no I/O needed
to land. This is the steady-state CI pattern.
Worked Example: Forced Re-anchor¶
An upstream re-tagged v0.1.0 to a different commit:
Locking dependency: fastc-core-cli
error: dependency 'fastc-core-cli': fetched tree no longer matches the recorded
sha256 (a1b2c3d4 != 9b1f3c5e). Re-run with `--force` if this is intentional.
Exit code: 1. The lock file is now out of sync with the fetched tree — either upstream was rewritten or the local cache is corrupt. After auditing the diff:
Exit code: 0. Commit the updated fastc.lock alongside whatever else
prompted the version bump.
CI Pattern¶
There is no --check flag yet. The CI-equivalent recipe is:
If fastc lock leaves fastc.lock unchanged, the working tree stays
clean and git diff --exit-code returns 0. If lock state drifted (someone
edited fastc.toml without re-running fastc lock), the diff is non-empty
and CI fails. A first-class --check is on the v1.x roadmap.
See Also¶
- Add — the front door for adding a new dependency. Runs
lockfor you after appending the entry. - Compile — how
dep_content_hashfeeds into the build cache key. - fastc-core — the standard library shipped as individually-locked git deps.