Repository navigation
feat(lib): record written_against and per-key provenance in the shared setup writer #9809
Description
Refs #6594. Slice 2 of 4. Blocked by #9801 (slice 1, the owner doc). Runs in parallel with slice 4.
Problem
No shared setup writer can tell a team-chosen value from an inherited default, so when a plugin changes a recommended default, apply cannot know whether to update the stored value (#6594 Problem 5). lib/setup-apply.mjs on origin/main validates and writes <home>/<plugin>.yaml but records neither the plugin version the file was written against nor a per-value source. Only developer-experience records provenance, and only for its prose file (plugins/developer-experience/skills/setup/reference/conventions-file.md, written_against front matter and per-section source=chosen|default markers).
Fix
In lib/setup-apply.mjs (and the generated per-plugin copies through scripts/sync-shared-copies.sh):
- Write a top-level
written_against: <plugin>@<version>when the writer writes the file, read from the plugin's.claude-plugin/plugin.json. - Record per key whether the team chose it or it was inherited, in a separate top-level
provenance:map (<key>: chosenfor a value the operator set or confirmed,<key>: defaultfor one filled at the plugin default). Values stay flat where they are today, so no existing reader (lib/config-cascade.mjs,lib/parse-concern-value.sh,scripts/check-convention-yaml.sh, the plugins' JSON Schemas) changes what it parses; allow the two new top-level keys where the writer validates. Keep reading a file without provenance (treat its values aschosen, report INFO once). --check: list eachdefaultvalue whose plugin default changed sincewritten_against(INFO), and eachchosenvalue whose default changed, with the old and new default (WARN, never rewritten).- Writing with
--yes: updatedefaultvalues to the new plugin default and print each change; never change achosenvalue. - Document the shape in the
## Provenancesection ofdocs/conventions/setup-lifecycle/README.md.
Prose files keep developer-experience's per-section markers; this slice does not change them.
Done when
-
bash lib/setup-apply.test.shexits 0, with new cases for:written_againstwritten on create; adefaultvalue updated after a default change; achosenvalue kept and reported WARN with old and new defaults; a file without provenance read with one INFO line -
bash scripts/sync-shared-copies.sh --checkexits 0 -
bash lib/config-cascade.test.shandbash lib/parse-concern-value.test.shexit 0, with one new case each reading a file that carrieswritten_againstandprovenance:and returning the same value as the file without them -
grep -c 'written_against' docs/conventions/setup-lifecycle/README.mdprints 1 or more -
ci-statusis green on the PR head
Activity
github-actions commentedon Oct 24, 2026
The triage sweep dispatched intake triage for this issue (attempt 2 of 2).
github-actions commentedon Oct 24, 2026
Proposed work class: work-class: scoped
Basis: automated intake triage; the lanes App applied this class.
Size: Medium
Complexity: Medium
Uncertainty: Known
Flags: none
Blocked by: none
Understood: extend the shared setup writer so it writes a top-level
written_against: <plugin>@<version>and a separateprovenance:map (chosen/default per key). It also adds--checkreporting and--yesupdates for default drift, and documents the shape in the setup-lifecycle README. The done-when items are specific and checkable. The issue names #9801 as a blocker, but it isn't in the open-issues list I was given, so I treated it as not blocking. No likely duplicates found.Automated triage, applied by the lanes App.
melodic-automation-lanes commentedon Oct 24, 2026
Not admitted to the issue lane: a Feature needs an open parent issue a listed human filed that awaits no decision. Admission takes the issue once each of those is met, when intake triages it again (
.github/actions/resolve-config/admission-rules.json).kyle-sexton commentedon Oct 26, 2026
Released for re-triage under the owner's 2026-10-26 rule: a person is involved only for "1. A change in original intent/vision 2. Something comes up during implementation ... that alters intent/vision or the primary design 3. If there is a HIGH/CRITICAL security issue". None applies here, so the hold label came off and intake triage runs again now.
To hold this issue again, add
needs-human(orstatus: needs-decision) and name which of the three applies.melodic-automation-lanes commentedon Oct 26, 2026
The latest triage verdict holds nothing: admission moved the issue to
status: confirmed; its comment says why.kyle-sexton commentedon Oct 27, 2026
Released for re-triage under the owner's 2026-10-26 rule: a person is involved only for "1. A change in original intent/vision 2. Something comes up during implementation ... that alters intent/vision or the primary design 3. If there is a HIGH/CRITICAL security issue". None applies here, so the hold label came off and intake triage runs again now.
To hold this issue again, add
needs-human(orstatus: needs-decision) and name which of the three applies.