Repository navigation
Description
Where this was measured. Branch vps2f-1914-u5a, head ebd6d9e17df3bc0d3d234bb13dbe00b5be5be3bf (PR #2359), file src/utils/safeWriteJson.ts, 638 numbered lines. The chmod region is byte-identical to the region at the previous head 3901239982bc8fa3ad96996539b4845aaa25bb31: the only difference between those two commits in this file is the doc block above the function (git diff --numstat between them for this path is 6 additions and 4 deletions, all comment lines).
The finding. _copyTargetMode reads the target's mode (:595-597) and treats a read failure as advisory: :598-604 logs a non-ENOENT failure and proceeds on the staged file's own mode. A set failure is fatal: :606 runs await fs.chmod(stagedPath, mode) and :609-613 rethrows, on the reasoning (stated at :609-612) that the commit rename has not run yet, so aborting publishes nothing while publishing would land the staged mode on a file that was 0o600. The call site is :397, before the rename at :401.
- The consequence that the contract does not weigh: on a filesystem that cannot express the mode at all (a group-writable exFAT or equivalent mount owned by another user, where chmod of a freshly created file is denied rather than honored), every JSON overwrite through
safeWriteJsonaborts before publishing. The caller gets an error, the target keeps its previous content, and the staged file is unlinked by the teardown, so the write is not merely un-durable, it does not happen. Task-message and history overwrites are the readers that hit this on that class of filesystem. - The asymmetry is deliberate for credentials and is not the thing being questioned: the doc block at
:577-591explains that a widened 0o600 credential file stays widened until some later write copies the mode again. What is unhandled is the case where the denial says nothing about confidentiality because the filesystem has no mode to deny.
Reviewer ask, quoted. Thread 4512593911 (coderabbitai[bot], submitted 2026-11-09T12:14:53Z, last edited 2026-11-09T12:14:55Z), graded Major, Data Integrity and Integration, Heavy lift, at src/utils/safeWriteJson.ts:613: "Allow safe overwrites when staged chmod is denied." with "On a group-writable Linux exFAT mount owned by another user, chmod can fail even for a newly staged file. Task-message overwrites then fail and leave history stale." Its guidance reads: "Update the staged-file chmod failure handling in the safe-write flow to allow publication only when the staged file's actual permissions are verified safe; retain fail-closed behavior when they are unsafe or cannot be verified. Preserve the existing cleanup behavior for files that are not published, and do not assume chmod failure alone establishes that the staged permissions are safe."
Why this was escalated instead of fixed in place. Doing what the guidance asks means, after a denial, reading the staged file's mode back (fs.stat on the staged path), deciding which errno families mean "this filesystem cannot express modes" (ENOTSUP/EOPNOTSUPP/EPERM on FAT-family mounts) as opposed to a real POSIX denial, and keeping the credential property the doc block defends for the second class. That is a change to the mode-copy contract the #1912 head brought in for this function - the call site comment at :393-396 records that the two resolutions of this function differ on a permission property and that a row can only pass on one platform - so the decision belongs with whoever owns that contract, and a blind fix would trade a loud failure for a silent permission widening.
Price status. Unpriced, and it is production currency: any fix changes executable lines in src/utils/safeWriteJson.ts. #2359 is cap-refused at 1284 counted executable lines against the 500-line cap (measured with the gate's own selectFromGit on the branch leg from 5319fe91fb0caf4aa4ec66aac68fa03744ebbc23 and on the CI leg against the merge of ebd6d9e17df3bc0d3d234bb13dbe00b5be5be3bf with tip 18861b2e357203e6cb4d93930aa2ed122b1eecea), and #2385, the unit that currently carries this file, is frozen at 526 counted executable lines pending a maintainer decision, so this cannot land on either. It travels with the follow-up branch the maintainer picks for the mode-copy contract.
What is not claimed. No measurement on a real exFAT mount was made from this Windows worktree: the class of filesystem, the denial, and the consequence are the reviewer's report plus what the code does on a denial, not an observation recorded here. No claim that publication is safe on any specific mount.
Found while answering CodeRabbit threads on #2359. Filed on the ruling that a finding recorded only inside a review reply gets collapsed, marked outdated and re-scored, while an issue does not.
Activity