Summary
Field report from the same adopter as #345/#346 (greenfield .NET 10 / Rust CRDT library). straymark charter drift reports declared .sln and .csproj files as "Modified but NOT declared (scope expansion)" even though they are explicitly listed (in backticks) in the charter's ## Files to modify table. The parser silently drops them from the declared-set. This has recurred across three charters (CHARTER-01, -03, -04) and forces a manual "parser-FP vs. real-expansion" triage at every close.
What happened
CHARTER-04 declared these rows in ## Files to modify:
| `src/Weft.Server/Weft.Server.csproj` | New — ... |
| `tests/Weft.Server.Tests/Weft.Server.Tests.csproj` | New — ... |
| `Weft.sln` | Change — ... |
straymark charter drift CHARTER-04 --range <declaration>..<implementation> output:
Declared: 10 files
Modified: 16 files
INFO: Modified but NOT declared (4 files, scope expansion):
- Weft.sln
- src/Weft.Server/Persistence/DocumentStateFraming.cs
- src/Weft.Server/Weft.Server.csproj
- tests/Weft.Server.Tests/Weft.Server.Tests.csproj
Of the 4 flagged files, only DocumentStateFraming.cs was a genuine undeclared addition. The other 3 (Weft.sln, both .csproj) were declared but never entered the parsed declared-set — note Declared: 10 when the table had 13 path rows.
Root cause (hypothesis)
The declared-path extractor appears to use an extension allowlist for "code" files (.cs, .rs, .md, .yaml, …) that omits build/project files (.sln, .csproj).
Earlier field notes (CHARTER-03) attributed this to "root paths without a /" (Weft.sln) or "adjacency to a sibling such as Program.cs". CHARTER-04 rules both out: the .csproj paths here DO contain / (src/Weft.Server/…) and are not adjacent to any matched sibling, yet they still fail. The common factor is the extension, not the path shape.
Why it matters
- Recurring false positives on every .NET charter that touches the solution or a project (CHARTER-01, -03, -04). The operator must re-triage parser noise vs. a real scope expansion (
DocumentStateFraming.cs) at every close.
- Erodes the signal: if "scope expansion" always ships ≥3 FPs, it gets normalized — and a genuinely undeclared change can slip through unnoticed.
- Bidirectional: because these paths never enter the declared-set, they can neither be correctly matched as declared-and-modified nor surface under "Declared but NOT modified".
Proposal (any subset)
- Extend the extension allowlist to include project/build files:
.sln, .csproj, .fsproj, .vbproj, .props, .targets (and equivalents in other ecosystems).
- Better: stop filtering the declared-set by extension entirely — treat any backtick-quoted token in the table's first column as a declared path. The charter already marks the path with backticks; that is the explicit declaration.
Context
Summary
Field report from the same adopter as #345/#346 (greenfield .NET 10 / Rust CRDT library).
straymark charter driftreports declared.slnand.csprojfiles as "Modified but NOT declared (scope expansion)" even though they are explicitly listed (in backticks) in the charter's## Files to modifytable. The parser silently drops them from the declared-set. This has recurred across three charters (CHARTER-01, -03, -04) and forces a manual "parser-FP vs. real-expansion" triage at every close.What happened
CHARTER-04 declared these rows in
## Files to modify:straymark charter drift CHARTER-04 --range <declaration>..<implementation>output:Of the 4 flagged files, only
DocumentStateFraming.cswas a genuine undeclared addition. The other 3 (Weft.sln, both.csproj) were declared but never entered the parsed declared-set — noteDeclared: 10when the table had 13 path rows.Root cause (hypothesis)
The declared-path extractor appears to use an extension allowlist for "code" files (
.cs,.rs,.md,.yaml, …) that omits build/project files (.sln,.csproj).Earlier field notes (CHARTER-03) attributed this to "root paths without a
/" (Weft.sln) or "adjacency to a sibling such asProgram.cs". CHARTER-04 rules both out: the.csprojpaths here DO contain/(src/Weft.Server/…) and are not adjacent to any matched sibling, yet they still fail. The common factor is the extension, not the path shape.Why it matters
DocumentStateFraming.cs) at every close.Proposal (any subset)
.sln,.csproj,.fsproj,.vbproj,.props,.targets(and equivalents in other ecosystems).Context