daily-fix: Step 10d durable markers record wrong SHA and emp
Highlight text on any card (body, plan, or an event) to anchor a comment, or leave a whole-task comment here. Mention @claude to summon a reply.
No comments yet.
Overview / Motivation
Auto-filed by the /daily 2026-07-26 problem sweep (route 2). Surfaced by 4 independent miner group(s) over the 2026-07-26 session transcripts.
Goal
Give Step 10d an authoritative merge-SHA derivation, require the --file form for
note-bearing markers whose prose embeds command substitutions, and make the canonical
Step-0 task-state read total on an empty marker note.
Workflow gap
- Bug observed: Three ways the Step 10d / Step 0 recipes produced wrong or empty durable records on 2026-07-26 — an
epm:merged v1recording a SIBLING task's merge SHA, a broken nested command substitution leaving a durable marker field silently blank, and the canonical Step-0 events read raisingIndexErroron a marker with an empty note (2 firings in 90 seconds, one cancelling a parallelCronCreate). - Why it is a workflow gap: Step 10d tells the session to post
epm:merged v1"with the list of merge SHAs" but supplies NO derivation recipe, so each session improvises one — and one improvisation read the sharedorigin/maintip, which concurrent sessions move; separately the committed one-liner at SKILL.md L6155 indexes[0]into a possibly-emptysplitlines(). - Confidence (emitter): high
- verified-at-filing:
grep -n 'MERGE_SHA\|merge_sha\|mergeCommit' .claude/skills/issue/SKILL.md→ 0 hits (absence-of-recipe: the Step 10d success bullet at L11273 reads "postepm:merged v1with the list of merge SHAs plusmerge_form:… andmerge_attempts:" and names no derivation);grep -rn 'mergeCommit' .claude/ scripts/→ 0 hits repo-wide outside worktrees (the authoritativegh pr view --json mergeCommitcall appears nowhere in the workflow surface).grep -n 'splitlines()\[0\]' .claude/skills/issue/SKILL.md→ 1 hit, L6155:print(e["ts"], e["kind"], (e.get("note") or "").splitlines()[0][:140])(the miners cited L6154; the live line is 6155).grep -n 'nested \$(\|heredoc' .claude/skills/issue/SKILL.md→ 0 hits bearing on--notecomposition.git log --oneline --since='7 days ago' -- .claude/skills/issue/SKILL.md→ 12 commits, none touching any of the three sites (2026-07-26)
Evidence
- Session
06447a89, 09:18:56Z: the session derived the merge SHA withgit -C "$REPO_ROOT" log -1 --format=%H origin/mainaftersync_repo_root.py; because sibling sessions merge concurrently, the tip at that instant was task #1692's merge commit. The durable marker recordedSUBJECT: task #1692: epm:merged — Merge landed.underMERGE_SHA=8426f64796…for task #1691. The session noticed only because the subject line named the wrong task, and posted a v2 correction:"**merge_sha: 262c69ade1…** (correcting v1 which quoted a sibling task #1692's merge commit that happened to be at origin/main tip …)". The correction usedgh pr view <PR> --json mergeCommit, which was available all along. - Same session, same command: the SHA substitution was embedded as
$(git -C \"$REPO_ROOT\" log -1 --format=%H origin/main)inside an already-double-quoted--note "…". The backslash-escaped quotes reached git literally —"fatal: cannot change to '\"/home/thomasjiralerspong/explore-persona-space\"': No such file or directory"(1 firing event) — so the substitution produced empty output and the marker's "verdict sha-bound to " field shipped blank. Afatal:line inside a Bash result is not a nonzero exit here, so nothing flagged it. - Session
6b3fca14, 07:07:44Z and 07:08:39Z: the Step-0 events read raised"IndexError: list index out of range"twice in the session's first 90 seconds (2 firing events), and the second firing cancelled a parallelCronCreatefor the/issue-tick 1693backstop —"<tool_use_error>Cancelled: parallel tool call Bash(uv run python scripts/task.py view 1693 …) errored</tool_use_error>"— which had to be re-issued. - Session
a2c4bae3, 14:53:56Z: the same expression failed on that session's FIRST tool call —"IndexError: list index out of range … === recent events (last 15) ===" (empty)— so the session started blind to its own event history and had to re-query. - Measured cost is small per firing (~1 min plus a re-issued cron arm; one re-query) but the failure sites are the session's first state read and its last durable provenance record. On a less observant run the sibling's SHA would have stood as #1691's permanent merge record.
Proposed change
.claude/skills/issue/SKILL.mdStep 10d success bullet (L11273): add the authoritative derivation —gh pr view <PR> --json mergeCommit -q .mergeCommit.oid— and state that a tip read (git log -1 origin/main) is NOT valid, because concurrent sessions move the shared tip between the merge and the read. This is an ADDITION, not a replacement: no derivation recipe exists at that site today.- Same site: require the marker's own subject/task id to be cross-checked against the derived SHA's commit subject before posting, so a foreign SHA is caught at post time rather than by eye.
.claude/skills/issue/SKILL.mdStep 10d and the CLAUDE.md § Task Workflow APIpost-markerguidance: for any note-bearing marker whose prose quotes git verbs or embeds a command substitution, preferpost-marker --file <path>(the flag is--file, mutually exclusive with--note) — building the note body in a file with every$( )resolved into a shell variable FIRST. Never nest a command substitution inside an already-quoted--note "…". The--fileform additionally sidesteps the repo-root guard's prose matching on git verbs..claude/skills/issue/SKILL.mdL6155: replace(e.get("note") or "").splitlines()[0][:140]with the total form((e.get("note") or "").splitlines() or [""])[0][:140], and apply the same total form to the Step-0 task-state read recipe so the copied one-liner is safe wherever it is pasted.- Grep the workflow surface for any sibling copy of the
splitlines()[0]idiom before landing — the live SKILL.md carries exactly one, but the recipe is copied by hand into session shell and may have been mirrored into another spec. - Add a pin test that the Step-0 enumerator one-liner handles an event whose
noteis empty or whitespace-only without raising.
Scope / surfaces
- Primary target:
.claude/skills/issue/SKILL.md CLAUDE.md(§ Task Workflow APIpost-markerguidance — the--filepreference for command-substitution-bearing notes)
Constraints / invariants
- Workflow-surface only — never experiment code,
configs/, ortasks/. uv run python scripts/workflow_lint.pypasses (no-flags); ruff clean on touched files.- This session runs under a
workflow_fix_target:Provenance line — it MUST NOT auto-route its own subagents' workflow-fix candidates (recursion guard).
Provenance
-
sha-verify (filing-time, #1467):
06447a89cited in commit context does NOT resolve as a commit in this repo at filing time — treat as a transcript/session reference, not a commit. -
fingerprint: 5b77e91f3661
-
workflow_fix_target: .claude/skills/issue/SKILL.md
-
fingerprint: PENDING
/daily 2026-07-26 route-2 filing. Miner refs: E-P9, E-P10, D-P4, B-P14.