| id | 2606111050 | |
|---|---|---|
| title | Guard schema.chmodFile with a mutex like fix.chmodFile | |
| status | ✅ | |
| summary | internal/schema has an injectable chmodFile var with no mutex, unlike internal/fix which added chmodFileMu in plan 247. Any concurrent test injection races on the schema var. | |
| model | ||
| depends-on |
|
Add a chmodFileMu sync.Mutex to
internal/schema to protect the injectable
chmodFile var, matching the pattern already
used in internal/fix.
Plan 247 added chmodFile to internal/fix and
internal/schema. The fix package also got
chmodFileMu and a mutex-guarded test. The
schema package did not.
A test that injects schema.chmodFile while the
production path reads it races. No such test
exists yet. The pattern invites one without the
mutex.
Mirror the internal/fix pattern exactly:
var chmodFileMu sync.MutexProduction callers lock, copy, and unlock before calling:
chmodFileMu.Lock()
fn := chmodFile
chmodFileMu.Unlock()
if err := fn(path, mode); err != nil {
return err
}Test injections hold the mutex around the assignment and the cleanup restore.
- Add
var chmodFileMu sync.Mutextointernal/schema(in the non-build-tagged file that already imports thechmodFilevar). - Wrap every production call to
chmodFileininternal/schemawith the lock/copy/unlock pattern. - If a coverage test for the schema chmod error path does not yet exist, add one — holding the mutex around the injection and restore.
- Verify: run
go test -race ./internal/schema/...with concurrent invocations to confirm no data race.
-
internal/schemahaschmodFileMu sync.MutexalongsidechmodFile - Every production read of
chmodFileininternal/schemauses the mutex - A test covering the chmod error path
in
internal/schemaholds the mutex around injection and restore -
go test -race ./internal/schema/...reports no data race - All tests pass:
go test ./... -
go tool golangci-lint runreports no issues (tools/go.mod requires ≥ 1.25.8; environment has 1.25.0 — cannot verify here)