`trellis init` corrupts the manifest hash of mixed-ownership files under `.trellis/` (e.g. `config.yaml`), causing the next `trellis update` to silently overwrite user customizations
Bug Description
trellis init --<platform> (the "add platform to an existing project" path) rewrites .trellis/.template-hashes.json by re-hashing every file under .trellis/ against its current on-disk content. For mixed-ownership files such as .trellis/config.yaml this records the user-modified content as the baseline, erasing the "Modified by you" protection. The next trellis update then classifies the file as "Template updated (will auto-update)" and silently overwrites the user's customizations.
Per update.js's own comment, mixed-ownership files (AGENTS.md, .github/copilot-instructions.md, .trellis/config.yaml) are supposed to differ from their recorded template hash — that difference is what triggers the "Modified by you (need your decision)" branch and protects local edits. But initializeHashes() (dist/utils/template-hash.js, ~L275) recursively walks all of .trellis/ and stores computeHash(currentContent) per file. EXCLUDE_FROM_HASH only excludes workspace/, tasks/, spec/, .developer, .backup-*, .version, .gitignore, .template-hashes.json — not config.yaml, workflow.md, scripts/, or agents/. So after init, config.yaml's manifest entry equals the local customized hash → update treats it as unmodified and overwrites it.
Related: #575 fixed the same class of receipt problem on the update path (writing back unchangedFiles); this is the parallel defect on the init path (initializeHashes re-baselining user-owned files).
Steps to Reproduce
trellis inita project; edit.trellis/config.yaml(e.g. setsession_commit_message: "custom"andcodex.dispatch_mode: inline).- Run
trellis update --dry-run→config.yamlcorrectly shows under "Modified by you (need your decision)". - Run
trellis init --dsh(or any platform) to add a platform. - Run
trellis update --dry-runagain →config.yamlhas moved to "Template updated (will auto-update)". The manifest now stores the customized content's hash. - A subsequent plain
trellis updatesilently overwrites the customizations.
Suggested fix: initializeHashes should not re-baseline files the user may own. Either (a) exclude .trellis/config.yaml and other mixed-ownership paths from the .trellis/ re-hash, matching update.js's mixed-ownership set; or (b) only record hashes for files init actually wrote in that invocation (scope the re-hash to reinitWritten / the newly-added platform's file set), not the whole .trellis/ tree.
Trellis Version
@mindfoldhq/trellis 0.7.0-beta.4 (also present on the 0.6.x line; observed while running trellis init --dsh --devin on a project whose config.yaml carried local customizations)
Node.js Version
v24
Operating System
Windows
Source: mindfold-ai/Trellis