promote: sweep the remaining fixed /tmp scratch paths onto a per-run convention #417

Open
opened 2026-08-26 16:19:24 +00:00 by jbr870 · 0 comments
Owner

Deferred from #47 QA round 1, finding CR-18 (qa-report:v1 domain=code phase=validate, comment 2201). Disposition defer-to-issue, decided by the operator on 2026-08-26.

The gap

plugin/skills/promote/SKILL.md writes several scratch JSON files to fixed, guessable /tmp paths 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 — no mktemp, 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:promote runs 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 that result.json was written only at the end of a wait and read unconditionally afterwards, so a crashed wait let a previous release's green gate a new tag. That consequence does not exist here.

Proposed fix

Sweep these three onto whatever per-run scratch convention the CR-1 fix 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-/tmp shape 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 from F-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.

Deferred from **#47 QA round 1**, finding `CR-18` (`qa-report:v1` domain=code phase=validate, comment 2201). Disposition `defer-to-issue`, decided by the operator on 2026-08-26. ## The gap `plugin/skills/promote/SKILL.md` writes several scratch JSON files to **fixed, guessable `/tmp` paths** 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 — no `mktemp`, 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:promote` runs 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 that `result.json` was written only at the end of a wait and read unconditionally afterwards, so a crashed wait let a previous release's `green` gate a new tag. That consequence does not exist here. ## Proposed fix Sweep these three onto whatever per-run scratch convention the `CR-1` fix 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-`/tmp` shape 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 from `F-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.*
Sign in to join this conversation.
No description provided.