Summary
SpecSync 6.0.0 cannot finish change check in a repository containing unchanged, tracked Git LFS assets, even when the change only touches code/specs and the asset directories are outside the configured source scope and listed in SDD ignored_paths.
Confirmed by rerunning the real command in CorvidLabs/peck and tracing the matching v6.0.0 source. This is a workspace-evidence compatibility problem, not a Godot failure or missing requirement-evidence row.
Reproduced environment
- macOS;
specsync --version → specsync 6.0.0.
- Consumer: CorvidLabs/peck at a3f08ca, branch
refactor/enemy-scene-presentation.
- Approved change:
let-enemy-scenes-own-animation-facing-and-damage-presentation-without-changing-combat-rules.
- The change's tasks and requirement-evidence table are populated. The strict module/spec coverage check passes; all 18 Godot suites passed separately.
- No asset archives or NFT sources changed between the refactor base
03a1082 and this head.
Relevant .specsync/config.toml:
source_dirs = ["godot"]
source_extensions = ["gd"]
exclude_dirs = [".godot", "build", "content", "fonts"]
Relevant .specsync/sdd.json:
{
"meaningful_paths": ["godot/", "tools/asset-library/", "scripts/godot-preview-plugin.mjs", "fledge.toml", ".specsync/sdd.json", ".specsync/config.toml", ".specsync/registry.toml", ".specsync/version"],
"ignored_paths": [".specsync/", "specs/", "assets/archives/", "assets/nfts/"]
}
.gitattributes:
assets/archives/*.tar.zst filter=lfs diff=lfs merge=lfs -text
assets/nfts/**/*.png filter=lfs diff=lfs merge=lfs -text
Actual reproduction
In that checkout, using the existing installed binary:
specsync change check let-enemy-scenes-own-animation-facing-and-damage-presentation-without-changing-combat-rules
Exits 1:
error: Git `filter` attribute is not supported for canonical evidence: `assets/archives/2d-animals-mega-pack-1.tar.zst`
Checks establishing why this is unrelated to the implementation:
git check-attr filter -- assets/archives/2d-animals-mega-pack-1.tar.zst
# assets/archives/2d-animals-mega-pack-1.tar.zst: filter: lfs
git diff --name-only 03a1082 a3f08ca -- assets/archives assets/nfts
# no output
fledge run spec-check
# 4 specs passed, 0 warnings/failures; 90/90 source coverage
The preceding player-scene change hits the same archive/error. No LFS fetching or tool installation is necessary to establish the attribute rejection; it also occurred when the local archives were LFS pointer files. Current reproduction confirms attribute rejection without modifying the asset configuration.
Source trace (v6.0.0)
check_change verification construction records workspace_digest: project_input_digest(root)? after the spec/code evaluation.
project_input_digest_uncached calls stable_discovered_evidence(root, None, ...), i.e. without scoped paths. Git inventory includes tracked files; filtering here uses the hardcoded volatile-path predicate, not SDD ignored_paths.
stable_discovered_evidence_with_hook_internal discovers that inventory and passes it into Git inspection.
inspect_git_candidates validates content attributes for clean, present regular files.
validate_git_attribute_output rejects any filter value other than unspecified/unset, including lfs, producing the exact observed error.
The same implementation was present in the inspected upstream main source at c8518b9b91176c664256d290fed4310ec0c12929. I did not build or run a separate upstream binary.
Expected outcome / acceptance
- A supported, integrity-preserving route for completing scoped changes in repositories with Git LFS assets.
- Explicit canonical semantics for LFS pointer versus hydrated content, or a documented evidence-scope policy that safely excludes unrelated asset trees. Do not blanket-disable content-attribute validation or make protected evidence silently skippable.
- Regression coverage for an otherwise valid approved source-only change plus an unchanged tracked LFS pointer outside its scope and in
ignored_paths.
- Coverage for both pointer-only and hydrated checkouts, and an in-scope LFS input so the chosen policy cannot hide meaningful changes.
- Clarify that current
ignored_paths controls meaningful-change policy but does not exclude files from the whole-workspace digest. The current error gives no usable recovery path for this normal repository layout.
Duplicate check
Searched all-state issue results for LFS and the exact phrase canonical evidence, and inspected recent reports. No matching issue was returned. Peck's earlier consumer-side report is CorvidLabs/peck#13; that ticket is closed, but the failure remains reproducible with the installed 6.0.0 binary and the configurations above.
Summary
SpecSync 6.0.0 cannot finish
change checkin a repository containing unchanged, tracked Git LFS assets, even when the change only touches code/specs and the asset directories are outside the configured source scope and listed in SDDignored_paths.Confirmed by rerunning the real command in CorvidLabs/peck and tracing the matching v6.0.0 source. This is a workspace-evidence compatibility problem, not a Godot failure or missing requirement-evidence row.
Reproduced environment
specsync --version→specsync 6.0.0.refactor/enemy-scene-presentation.let-enemy-scenes-own-animation-facing-and-damage-presentation-without-changing-combat-rules.03a1082and this head.Relevant
.specsync/config.toml:Relevant
.specsync/sdd.json:{ "meaningful_paths": ["godot/", "tools/asset-library/", "scripts/godot-preview-plugin.mjs", "fledge.toml", ".specsync/sdd.json", ".specsync/config.toml", ".specsync/registry.toml", ".specsync/version"], "ignored_paths": [".specsync/", "specs/", "assets/archives/", "assets/nfts/"] }.gitattributes:Actual reproduction
In that checkout, using the existing installed binary:
Exits 1:
Checks establishing why this is unrelated to the implementation:
The preceding player-scene change hits the same archive/error. No LFS fetching or tool installation is necessary to establish the attribute rejection; it also occurred when the local archives were LFS pointer files. Current reproduction confirms attribute rejection without modifying the asset configuration.
Source trace (v6.0.0)
check_changeverification construction recordsworkspace_digest: project_input_digest(root)?after the spec/code evaluation.project_input_digest_uncachedcallsstable_discovered_evidence(root, None, ...), i.e. without scoped paths. Git inventory includes tracked files; filtering here uses the hardcoded volatile-path predicate, not SDDignored_paths.stable_discovered_evidence_with_hook_internaldiscovers that inventory and passes it into Git inspection.inspect_git_candidatesvalidates content attributes for clean, present regular files.validate_git_attribute_outputrejects anyfiltervalue other thanunspecified/unset, includinglfs, producing the exact observed error.The same implementation was present in the inspected upstream main source at
c8518b9b91176c664256d290fed4310ec0c12929. I did not build or run a separate upstream binary.Expected outcome / acceptance
ignored_paths.ignored_pathscontrols meaningful-change policy but does not exclude files from the whole-workspace digest. The current error gives no usable recovery path for this normal repository layout.Duplicate check
Searched all-state issue results for
LFSand the exact phrasecanonical evidence, and inspected recent reports. No matching issue was returned. Peck's earlier consumer-side report is CorvidLabs/peck#13; that ticket is closed, but the failure remains reproducible with the installed 6.0.0 binary and the configurations above.