promote: sweep the remaining fixed /tmp scratch paths onto a per-run convention #417
Labels
No labels
component:adapters
component:lifecycle
component:qa
component:setup
component:shared
component:worktrees
phase/accepted
phase/backlog
phase/deployed
phase/developing
phase/integrating
phase/planning
phase/qa
phase/requirements
phase/uat
priority:critical
priority:critical
priority:high
priority:high
priority:low
priority:low
priority:medium
priority:medium
type:bug
type:chore
type:docs
type:feature
type:infra
type:tech-debt
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
jbr870/devwork-skills#417
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Deferred from #47 QA round 1, finding
CR-18(qa-report:v1domain=code phase=validate, comment 2201). Dispositiondefer-to-issue, decided by the operator on 2026-08-26.The gap
plugin/skills/promote/SKILL.mdwrites several scratch JSON files to fixed, guessable/tmppaths on lines #47 did not touch:/tmp/promote-produced.json(:578, consumed at :582)/tmp/promote-findings.json(:625, consumed at :636)/tmp/promote-pending.json(:632, consumed at :636)Each is created with a plain
>redirect — nomktemp, no per-run uniqueness, no symlink check.Why it matters, and why it is less urgent than CR-1
This repo's CLAUDE.md documents multiple concurrent sessions on one host, so two
/dev:promoteruns share these paths and clobber each other. On a multi-user host the usual pre-planted-symlink exposure applies too.But unlike its sibling
CR-1— fixed in #47 — these files are written and immediately consumed within the same step, so there is no window in which a stale file from a previous run is read as this run's state. CR-1's danger was specifically thatresult.jsonwas written only at the end of a wait and read unconditionally afterwards, so a crashed wait let a previous release'sgreengate a new tag. That consequence does not exist here.Proposed fix
Sweep these three onto whatever per-run scratch convention the
CR-1fix in #47 establishes (a unique per-run directory), so promote has one scratch discipline rather than two.Do this after #47 merges — it should follow #47's pattern, not invent a second one.
Wider question worth asking once
The same fixed-
/tmpshape likely appears in other skills' emitted fences. A survey (and, if it is widespread, a line in the CLAUDE.md portability baseline about scratch-file discipline in skill-emitted shell) may be worth more than fixing promote alone. Related in spirit to the deferred--flag-as-last-argument family sweep fromF-PO-47-3-2: both are "the fix landed where the finding pointed, not everywhere the rule lives".Why it was not fixed in #47
Pre-existing, on unchanged lines, and without CR-1's stale-verdict consequence. Sweeping it belongs with the scratch-discipline convention rather than with the pipeline-identity feature.
Filed by QA round 1 on issue #47. Component:
component:lifecycle(promote). Depends on: #47 merging first.