Merge origin/main (v1.64.0.0) into garrytan/time-attack-fork-review

Both waves fixed several of the same bugs; resolutions keep whichever
shape this branch's tests pin (#2018 jq bind, #1798 set-- pattern,
stop-ack, lock errors, polyfill windowsHide) and take main's richer
codex Step 2A (it absorbed the same mktemp fix). True unions: memory-
ingest keeps main's capability-probed --include-gitignored inside our
GIT_CEILING defense; setup wraps main's Playwright platform override in
our stale-healing install lock; package.json takes main's diff@^9 and
the combined test glob (design/test + ios-qa/daemon/test, 30s timeout).
Generated SKILL.md files regenerated from resolved templates, never
hand-picked. Ship goldens refreshed; parity/carve budgets re-measured
for the summed preamble growth of both waves (itemized per entry).
This commit is contained in:
Garry Tan committed 2026-08-15 09:57:34 -07:00
commit 7898b80686
241 files changed
+7683 -4716

No files matched your search

+30
View File
@@ -78,6 +78,26 @@ describe('restrictDirectoryPermissions', () => {
fs.mkdirSync(d);
expect(() => restrictDirectoryPermissions(d)).not.toThrow();
});
test('on Windows, the directory stays usable by the calling process', () => {
if (process.platform !== 'win32') return;
const d = path.join(tmpDir, 'still-usable');
fs.mkdirSync(d);
fs.writeFileSync(path.join(d, 'before'), 'x');
restrictDirectoryPermissions(d);
// Regression: an unqualified username passed to icacls can resolve to
// the machine SID rather than the user account. Combined with
// /inheritance:r that leaves a directory whose only ACE matches nobody,
// so the process that just "secured" it can no longer enumerate or
// write to it. icacls still reports success, so a not-toThrow assertion
// sails straight past it — hence these access checks.
expect(() => fs.readdirSync(d)).not.toThrow();
expect(fs.readdirSync(d)).toContain('before');
expect(() => fs.writeFileSync(path.join(d, 'after'), 'y')).not.toThrow();
expect(fs.readFileSync(path.join(d, 'after'), 'utf8')).toBe('y');
});
});
describe('writeSecureFile', () => {
@@ -139,6 +159,16 @@ describe('mkdirSecure', () => {
expect(() => mkdirSecure(d)).not.toThrow();
});
test('on Windows, the created directory stays usable by the caller', () => {
if (process.platform !== 'win32') return;
// The state-dir path that broke: mkdirSecure() creates .gstack/, hardens
// it, and the very next thing the daemon does is write a lockfile inside.
const d = path.join(tmpDir, 'state', '.gstack');
mkdirSecure(d);
expect(() => fs.writeFileSync(path.join(d, 'browse.json.lock'), '1')).not.toThrow();
expect(fs.readdirSync(d)).toContain('browse.json.lock');
});
test('recursive behavior: creates intermediate directories', () => {
const d = path.join(tmpDir, 'a', 'b', 'c');
mkdirSecure(d);