Repository navigation
Description
Refs #9737
Blocked by: the ai-slop child (chore(ai-slop): drop the one-release .claude/ai-slop.json team read). Until it merges, deleting .claude/ai-slop.json makes scripts/check-purged-em-dashes.sh exit 2 (:137).
Host-run: a session pull request, for two reasons.
- It changes the
/attribution:setupskill body and its eval casejson-fallback-layer-moves-whole(plugins/attribution/skills/setup/evals/evals.json:107-118), which the lane cannot run. - It deletes files under
.claude/, which the lane mounts read-only (chore: drop the one-release .claude config reads and this repository's old config files #12554).
Outcome
The attribution detectors read the team and personal layers only from <home>/attribution.yaml and <home>/attribution.local.yaml. The repo-relative .claude/attribution.json and .claude/attribution.local.json fallbacks are gone. The YAML reader landed in attribution 0.12.0 (plugins/attribution/CHANGELOG.md:288-296), and 0.16.0 has shipped since.
/attribution:setup can no longer find an old JSON file through --show-config, because that file no longer appears in the Config layers list. It reports the file as a retired config instead, through the plugin's retirements.yaml and check-retirements.sh, the same way it reports .claude/provenance.json.
This repository's .claude/attribution.json and .claude/ai-slop.json are deleted. Slice 3 has made the ai-slop file unread. The user-global ~/.claude/attribution.json layer stays (lib.sh:46, ADR 0075).
Change
plugins/attribution/skills/audit/scripts/lib.sh:53: drop the.claude/$name.jsonfallback, and update the comment at :34-41. Keep the user-global layer (:46) and the jq path that reads it.plugins/attribution/retirements.yaml: append twoaction: migraterecords,kind: file, one withpath: .claude/attribution.jsonand one withpath: .claude/attribution.local.json. Each successor names the YAML file under the convention home. Existing records are not edited.plugins/attribution/skills/setup/SKILL.md:22-27,60-66:- Replace the "layer still on its JSON fallback" detection with the retired-config finding.
- Keep the carry-every-key-into-the-YAML step for a found file.
- Rewrite eval case 9 (
json-fallback-layer-moves-whole) to match.
- Leave the eval samples in place:
plugins/attribution/evals/setup-check-writes-nothing/samples/names-team-layer.json:22is afailsample and stays valid.- The
no-write-config.jsonsamples are write-detection samples.
- Convert the test fixtures that configure a temp repo through
.claude/attribution*.json:check-stamps.test.sh,list-corpus.test.sh,score-golden.test.sh,sweep-ledger.test.shandlib.test.shmove todocs/conventions/attribution*.yaml. One case asserts that the old file is not read. - Docs:
plugins/attribution/schemas/attribution.schema.json:5description.plugins/attribution/README.md:95-97.plugins/attribution/skills/audit/SKILL.md:243.docs/contracts/config-cascade/README.md:782.- The
docs/conventions/attribution.yaml:2-10header: drop the "stays until the cleanup slice", "made in both files" and "as it was in .claude/attribution.json" text.
- Delete
.claude/attribution.json, and.claude/ai-slop.jsononce slice 3 has merged. - Run the attribution setup eval cases before and after the change, and put the result in the pull request.
- Add an attribution changelog fragment.
Done when
-
git ls-tree --name-only HEAD .claude/attribution.json .claude/ai-slop.jsonprints nothing. -
git grep -nP '(?<!~/)(?<!HOME/)(?<!\}/)\.claude/(attribution(\.local)?\.json|\$name\.json)' -- plugins/attribution docs/conventions/attribution.yaml docs/contracts ':!*CHANGELOG*' ':!*.test.sh' ':!plugins/attribution/evals' ':!plugins/attribution/retirements.yaml' ':!plugins/attribution/skills/setup/evals'prints nothing (onorigin/mainit prints 7 lines in 4 files). -
git grep -nE 'JSON fallback|\.claude/. JSON|its \.claude/attribution\.json fallback|still on its fallback' -- plugins/attribution ':!*CHANGELOG*' ':!plugins/attribution/retirements.yaml'prints nothing (onorigin/mainit prints 11 lines in 4 files). -
grep -n '^## \[0.13.0\]' plugins/attribution/CHANGELOG.mdprints one line (a release after the 0.12.0 YAML reader). -
bash scripts/check-purged-em-dashes.shexits 0. -
git grep -n 'path: .claude/attribution.json' -- plugins/attribution/retirements.yamlprints one line. -
git grep -n 'cfg_layer_add "${HOME:-/nonexistent}/.claude/attribution.json"' -- plugins/attribution/skills/audit/scripts/lib.shprints one line (the user layer stays). -
bash scripts/run-test-file.sh plugins/attribution/skills/audit/scripts/lib.test.shexits 0. -
bash scripts/run-test-file.sh plugins/attribution/skills/audit/scripts/check-stamps.test.shexits 0. -
bash scripts/run-test-file.sh plugins/attribution/skills/audit/scripts/list-corpus.test.shexits 0. -
bash scripts/run-test-file.sh plugins/attribution/skills/audit/scripts/score-golden.test.shexits 0. -
bash scripts/run-test-file.sh plugins/attribution/skills/audit/scripts/sweep-ledger.test.shexits 0. -
scripts/check-changelog-fragments.sh --check-required origin/mainexits 0.
Metadata
Metadata
Assignees
Labels
Type
Fields
Work status
Activity
github-actions commentedon Nov 5, 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: #13471
I understand this as a cleanup slice of #9737. It drops the
.claude/attribution.jsonand.claude/attribution.local.jsonrepo-relative fallbacks from the attribution detectors and keeps the user-global layer. It adds tworetirements.yamlrecords and reworks/attribution:setupand its eval case 9 to report a retired config. It also converts the test fixtures, updates the docs, deletes the two.claudeconfig files and adds a changelog fragment.The issue says it must wait for the ai-slop child, which looks like #13471. Deleting
.claude/ai-slop.jsonfirst would makescripts/check-purged-em-dashes.shexit 2.The done-when items are exact. The setup eval runs and the
.claude/deletions are host-run steps, and thehost-runlabel already covers them. I found no duplicate among the open issues.Automated triage, applied by the lanes App.
melodic-automation-lanes commentedon Nov 5, 2026
Not admitted to the issue lane: it carries host-run. Admission takes the issue once each of those is met, when intake triages it again (
.github/actions/resolve-config/admission-rules.json).melodic-automation-lanes commentedon Nov 5, 2026
The latest triage verdict holds nothing: admission moved the issue to
status: confirmed; its comment says why.kyle-sexton commentedon Nov 5, 2026