provenance (pin half): a dev-machine run executes skill text that can change underneath it #56
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#56
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?
Observation
Split out of #34 when its record half was promoted into a feature. #34 opened with two
independently useful halves — record (a run's Phase Outcome carries the suite version/SHA it
executed) and pin (a run resolves its skill text once, so the text cannot move underneath it).
The record half is now in flight. This issue carries what is left, narrowed by what #50 actually
delivered rather than restating #34's original framing.
#34's original evidence:
~/.claude/skills/_sharedon the desktop was a symlink into a live gitwork tree that received 20+ commits, including a merge, during a single run — one mid-QA commit
changed the QA playbook's preconditions between stage launches. The model noticed once and re-read
one file.
What #50 changed, and what it did not
The plugin migration solved this for consumers, and only for consumers:
~/.claude/plugins/cache/devwork-skills/dev/<VERSION>/~/.claude/skills/dev→~/Coding/devwork-skills/pluginSo the residual is precisely: a run on the machine where the suite is being developed executes
skill text that can change underneath it, and nothing prevents or even detects that. This is not
a hypothetical — it is where #34's original observation was measured, and the dev box is exactly
where the suite is dogfooded most heavily.
Why it is not simply "solved by installing the plugin here too"
Installing the released plugin on the dev box would pin it, but at the cost of the thing that makes
this box useful: changes must be exercised before they are released. The dev box deliberately
runs unreleased text. Any fix has to preserve "run what I just edited" while removing "and it may
change again halfway through."
Recurrence
Mechanical and permanent on the dev box; every multi-session or long-running day has this property.
Its consequence is now bounded to the dev machine, which is why this is filed at lower priority
than #34's record half — but note that the record half does not fix it, it only makes it
visible after the fact: a stamped SHA tells you the text moved, it does not stop it moving.
Hypothesis
Not yet designed. Candidate directions, cheapest first:
SHA at run start, re-probe at phase boundaries, and raise a loud finding if it changed. Turns a
silent confound into a visible one.
executes from that. Preserves "run what I just edited" as of run start; costs a copy per run and
a resolution step every skill would have to honour.
cases that matter (a QA sweep, a comparison across slots).
Direction 1 is a natural follow-on to #34 and may make 2/3 unnecessary; sequence accordingly.
Suggested lane
Full pipeline if it becomes a per-run resolution mechanism (2 or 3); possibly a small amendment
on top of #34's helper if it lands as detection (1). Decide after #34's record half ships.
Split out of #34 on 2026-08-24 during the fan-in that promoted #34's record half. #22, which #34
originally named as the home for pinning, is closed — superseded by #50.
Live dogfood evidence (2026-08-25, parallel wave 1): issue #61's requirements run recorded
suite: {"source":"git","sha":"07d9ad8","dirty":true}on PO-61-1 — while the session had beenlaunched when main stood at
7453ac5. Two distinct signals in that one stamp:~/.claude/skills/devsymlink) advanced7453ac5→07d9ad8during the run — the parallel metasession merged six amendments while two feature sessions executed skill text from that moving
checkout. The #57 provenance stamp made this visible per record (which is its job — the record
half), but nothing pinned what a given phase actually executed across its whole duration
(the pin half — this issue).
dirty:truewas caused by the untracked harness-managed.claude/worktrees/directory (where parallel-session worktrees live), not by edits toshipped files. Fixed by gitignoring the path (commit
cda2366), so future stamps report dirtyonly when tracked content actually diverges. Worth remembering at design time: the dirty flag
is repo-wide — anything untracked inside the checkout poisons it, so what the flag should
mean (shipped-tree divergence vs any divergence) is a pin-half design question.