Skip to content

chore(attribution): drop the one-release .claude/attribution.json team read #13476

Description

@kyle-sexton

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.

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.json fallback, 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 two action: migrate records, kind: file, one with path: .claude/attribution.json and one with path: .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:22 is a fail sample and stays valid.
    • The no-write-config.json samples 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.sh and lib.test.sh move to docs/conventions/attribution*.yaml. One case asserts that the old file is not read.
  • Docs:
    • plugins/attribution/schemas/attribution.schema.json:5 description.
    • 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-10 header: 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.json once 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.json prints 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 (on origin/main it 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 (on origin/main it prints 11 lines in 4 files).
  • grep -n '^## \[0.13.0\]' plugins/attribution/CHANGELOG.md prints one line (a release after the 0.12.0 YAML reader).
  • bash scripts/check-purged-em-dashes.sh exits 0.
  • git grep -n 'path: .claude/attribution.json' -- plugins/attribution/retirements.yaml prints one line.
  • git grep -n 'cfg_layer_add "${HOME:-/nonexistent}/.claude/attribution.json"' -- plugins/attribution/skills/audit/scripts/lib.sh prints one line (the user layer stays).
  • bash scripts/run-test-file.sh plugins/attribution/skills/audit/scripts/lib.test.sh exits 0.
  • bash scripts/run-test-file.sh plugins/attribution/skills/audit/scripts/check-stamps.test.sh exits 0.
  • bash scripts/run-test-file.sh plugins/attribution/skills/audit/scripts/list-corpus.test.sh exits 0.
  • bash scripts/run-test-file.sh plugins/attribution/skills/audit/scripts/score-golden.test.sh exits 0.
  • bash scripts/run-test-file.sh plugins/attribution/skills/audit/scripts/sweep-ledger.test.sh exits 0.
  • scripts/check-changelog-fragments.sh --check-required origin/main exits 0.

Activity

  1. added
    host-runNeeds an unattended run on a host; the host runner takes it, not a person or the issue lane.
    on Nov 5, 2026
  2. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Nov 5, 2026
  3. github-actions commented on Nov 5, 2026

    @github-actions
    Contributor

    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.json and .claude/attribution.local.json repo-relative fallbacks from the attribution detectors and keeps the user-global layer. It adds two retirements.yaml records and reworks /attribution:setup and its eval case 9 to report a retired config. It also converts the test fixtures, updates the docs, deletes the two .claude config 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.json first would make scripts/check-purged-em-dashes.sh exit 2.

    The done-when items are exact. The setup eval runs and the .claude/ deletions are host-run steps, and the host-run label already covers them. I found no duplicate among the open issues.

    Automated triage, applied by the lanes App.

  4. added
    priority: mediumReal value, no hard deadline; normal backlog flow.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Nov 5, 2026
  5. added
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.
    on Nov 5, 2026
  6. added
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    and removed
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    on Nov 5, 2026
  7. melodic-automation-lanes commented on Nov 5, 2026

    @melodic-automation-lanes
    Contributor

    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).

  8. melodic-automation-lanes commented on Nov 5, 2026

    @melodic-automation-lanes
    Contributor

    The latest triage verdict holds nothing: admission moved the issue to status: confirmed; its comment says why.

  9. self-assigned this
    on Nov 5, 2026
  10. kyle-sexton commented on Nov 5, 2026

    @kyle-sexton
    MemberAuthor
    No description provided.
  11. removed
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    host-runNeeds an unattended run on a host; the host runner takes it, not a person or the issue lane.
    on Nov 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

priority: mediumReal value, no hard deadline; normal backlog flow.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.

Type

Fields

Work status

confirmed

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions