Skip to content

Lock File

The .bonsai-lock.yaml file tracks every file generated by Bonsai. It stores content hashes (SHA-256) so Bonsai can detect when you have manually edited a generated file, enabling safe conflict resolution on subsequent runs.

When you run bonsai init, bonsai add, or bonsai update, Bonsai generates files into your project. The lock file records the hash of each file’s content at generation time. On the next run, Bonsai compares the current file’s hash against the lock to determine whether:

  • The file is unchanged (safe to overwrite silently)
  • The file was modified by the user (conflict — prompt for resolution)
  • The file does not exist on disk (safe to create)

The root object in .bonsai-lock.yaml.

FieldTypeRequiredYAML TagDescription
versionintYesversionLock file format version (currently 1)
filesmap[string]FileEntryYesfilesMap of relative file path to file entry

Each entry in the files map describes one tracked file.

FieldTypeRequiredYAML TagDescription
hashstringYeshashSHA-256 hex digest of the file contents at generation time
sourcestringNosourceOrigin identifier (e.g., catalog:skills/coding-standards, generated:settings-json, scaffolding:INDEX.md.tmpl)

The IsModified() method determines what to do with each file:

File exists on disk?Hash matches lock?Result
NoN/Aexists=false, modified=false — safe to create the file
YesNo lock entryexists=true, modified=true — file exists but is not tracked, treated as user-owned
YesHash matchesexists=true, modified=false — safe to overwrite silently
YesHash differsexists=true, modified=true — user has modified the file, conflict

When a conflict is detected, Bonsai prompts you with three options:

  • Skip — Leave your modified file as-is, do not update it
  • Overwrite — Replace your file with the new generated version
  • Backup & Overwrite — Save your file as filename.bak, then write the new version

Bonsai uses SHA-256 to hash file contents. The hash is computed from the raw file bytes using Go’s crypto/sha256 package and stored as a hex-encoded string.

func ContentHash(content []byte) string {
h := sha256.Sum256(content)
return hex.EncodeToString(h[:])
}

The source field records where the file came from. Common patterns:

PatternMeaning
catalog:skills/<name>Skill content from the embedded catalog
catalog:workflows/<name>Workflow content from the catalog
catalog:protocols/<name>Protocol content from the catalog
catalog:sensors/<name>Sensor script from the catalog
catalog:routines/<name>Routine content from the catalog
catalog:core/<name>Core file (identity, memory, self-awareness)
scaffolding:<path>Scaffolding template file
generated:settings-jsonAuto-generated .claude/settings.json
generated:workspace-claude-mdAuto-generated workspace CLAUDE.md
generated:routine-dashboardAuto-generated routine dashboard
generated:skill-workflow-<name>Auto-generated slash command skill file
generated:rule-skill-<name>Auto-generated path-scoped rule file

A snippet from Bonsai’s own .bonsai-lock.yaml:

version: 1
files:
.claude/settings.json:
hash: 28d8c6d219987d061ea9d568ebe52c776a19418f750a3038121b74ce8b349f54
source: generated:settings-json
station/CLAUDE.md:
hash: 05996db9e28e09e0459dcccb05b8bf47d3810d575db22111eff35852a3ffd533
source: generated:workspace-claude-md
station/INDEX.md:
hash: e6a864e9fab9c253dae4c2f314a124c73c9c9cb49dff20a2f9f594495b29a192
source: scaffolding:INDEX.md.tmpl
station/Playbook/Status.md:
hash: a7d8c0532c30f37f122b1584467d79a8fbb46854dce5ec781411c92826f51cf7
source: scaffolding:Playbook/Status.md.tmpl
  • Configuration — The .bonsai.yaml project config that the lock file tracks alongside
  • How Bonsai Works — The generation model and what files are created