mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-02 11:45:20 +02:00
0b723c437f
stageSkill writes a candidate skill into ~/.gstack/.tmp/skillify-<spawnId>/ with restrictive perms. commitSkill does an atomic fs.renameSync into the final tier path with realpath/lstat discipline (refuses symlinked staging dirs, refuses to clobber existing skills). discardStaged is the cleanup path for test failures and approval rejections, idempotent and bounded to the per-spawn wrapper. validateSkillName enforces lowercase/digits/ dashes only, no path-escape characters. Implements the D3 contract from the v1.19.0.0 plan review: never a half-written skill on disk. Test fail or approval reject = rm -rf the temp dir, no tombstone for never-approved skills. Closes Codex finding #5 (atomic skill packaging) for Phase 2a. 34 unit assertions covering: stage validation, file-path escape rejection, permission check, atomic rename, clobber refusal, symlink refusal, project tier unresolved, idempotent discard, end-to-end happy + simulated test failure + approval reject paths. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>