fix(claude-config): fix audit findings in audit-instructions, unhobble and permission lint - #5311
Conversation
The I15 ledger link used six ../ segments and resolved outside the repo; an installed plugin does not carry docs/, so name the path in code font. Refs #3568 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
…s and I32 tiers I31 and I33 now admit any file inside a skill directory (I33 excludes SKILL.md) plus context/, reference/, and references/ files, and I33 names the nearest ancestor SKILL.md as its hub. I32 is CRITICAL under plugins/ and IMPORTANT on a user or project surface. The persist-admission text in criteria.md and persist-findings.md names the scanner and lane intakes. Refs #4116, #4656 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
…g-ids surface_of() accepted every file under $HOME as a user: surface, so a row naming ~/.ssh/config or ~/.claude/.credentials.json got a finding id whose anchor hashed a line of that file. Claude Code reads CLAUDE.md, CLAUDE.local.md and AGENTS.md from the working directory and every directory above it, and follows imports to absolute paths, so the user surface stays home-wide. It now admits only instruction-file shapes: any markdown file, and settings.json, settings.local.json or hooks.json inside a .claude tree or the resolved CLAUDE_CONFIG_DIR. Anything else is refused as surface-not-an-instruction-file. The scope carries its four-part record in the code. relativize_in_repo in emit-findings.sh is unchanged. Tests cover accepted ancestor, AGENTS.md, import-target, settings, plugin hooks.json and relocated-config-dir shapes, refused non-instruction files, and symlink chains inside home, from the repository into home, and to a non-instruction target. Refs #4116 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
I31, I33 and I34 cover every file a skill loads, not only its markdown, so the home-directory instruction shapes also admit any file beneath a skills/ directory inside a .claude tree or the resolved CLAUDE_CONFIG_DIR, plugin cache included. A non-markdown file under a skills/ directory elsewhere in home stays refused, as do credentials, transcripts and dotfiles. Refs #4116 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
…d, point at the owners Refs #4113 The file restated the lane fraction and bytes per token that SKILL.md Lane sizing owns, carried a stale "emits I28 and I29 today" persist paragraph, and restated the finding tuple that reference/finding-identity.md owns. After turning each of those into a pointer, the only content no other file held was the I33 by plugin layout. That moves into SKILL.md Phase D, and the file is deleted rather than kept as a second home. SKILL.md and eval case 25 now point at Lane sizing, Run files and resume, reference/finding-identity.md and context/persist-findings.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
…laim and the I33 dispatch rule Drop ticket back-references from lane sizing and state the one partition rule. Give the subagent-window claim a four-part record and say where the lane model window comes from and what to pass when it does not resolve. Extend the read-only contract to the lane reports and run-state writes, state that I33 rows sit outside the per-lane verifier batches and count as one dispatch, assert it in eval 28, and restore line headroom. Refs #4114, #4115, #4656 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
…sk row Refs #4600 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
…dence An empty strip ledger now licenses deleting an editorial candidate only. A consequential rule the ledger did not defend goes back to a Deletion watch or is restored; only a closed watch makes its removal permanent, matching the attribution spec. The re-add grammar sentence now states the one-row versus two-row threshold asymmetry as this skill's rule. The watch is named in the mutating-step rail and the description triggers, the watch section says where qualifying sessions run and how they are counted, and criteria.md points its delete-and-watch sites at Deletion tiers. Eval 18 uses an unambiguous non-protected rule; eval 22 covers the empty-ledger case. Refs #3563 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
…convention oracle test, readd refusal Refs #4094 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
… argument status prints register holds, confounds and the PR URL with the source of each; readd gets a by-hand ledger-grouping report against the two-row gate; decide is documented as a presence-gated composition. Adds evals 27 to 30. Refs #4094 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
…ly permissions files Refs #4027. Independent review of the C2-defaultMode bypassPermissions change that reached main in #5154 without review. Defects fixed - permission-state.sh classified a settings file invalid-json when the LAST key under `permissions` was a string, because `jq -e` reads only the last output of a per-key check. `{"permissions":{"defaultMode":"bypassPermissions"}}` was rejected and never scanned, so C2-defaultMode (and C5-disableType) could not fire on real files, only on hand-written records. The check now tests only the allow, ask, and deny lists. Tests cover the reader and the reader-into-lint path and fail against the old reader. - Both C2-defaultMode findings now say to remove the value from the named file: an ignored project or local value still hides a user-scope defaultMode (auto falls to the built-in default, bypassPermissions to Manual). - The "v2.1.142 and later" boundary for auto had no source on any current page and is removed from the finding, the code comment, and the criteria row, which now records the absence and where it was checked. - The "acceptEdits, plan, and dontAsk still apply here" clause left the finding: the basis limits it to terminal sessions. Claims checked, fetched 2026-09-29 as whole raw pages - project and local settings ignore auto and bypassPermissions: settings-reference permissions.defaultMode Scope, permission-modes which-mode-a-session-starts-in. - bypassPermissions became ignored in v2.1.257: settings-reference Scope ("Before v2.1.257, bypassPermissions took effect from any file") and the changelog 2.1.257 entry. - the session starts in Manual: permission-modes, same section. - user and managed settings read both values: permission-modes switch-permission-modes. - other values apply from any file: permission-modes, same section. Tests added - plan, dontAsk, default, and manual in project scope raise no finding. - bypassPermissions fires in local and startdir-local, not in user or managed. - reader-into-lint over real files for the string-only shape. No defect found in docs/conventions/permission-rule-hygiene/README.md or babysit-prs/reference/safety.md; neither restates the project-scope claim beyond what the pages support. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
…shape check without history Refs #4027. The C2-defaultMode findings said an ignored project or local value makes the session start in the built-in default or Manual. That holds only when no higher-ranked settings file and no --permission-mode sets a mode ("settings precedence decides"), so both findings and the criteria row now carry that condition. The criteria row keeps the as-of date and the absence record for the auto version boundary; the lint and reader comments and the reader test state the rule in present tense and point to the row. The reader test also asserts that {"permissions":{}} is present. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
…nhobble state Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
…d where 0.51.7 shipped Refs #4027 In-place changelog corrections: - 0.51.18: body replaced by a pointer; it repeated the 0.51.16 Fixed entry (released by #5159) and the 0.51.10 Changed entry (released by #5161) - 0.51.17: body replaced by a pointer; it repeated the 0.51.15 entry (released by #5156) - 0.51.7: states it shipped through #5154 (commit 9c2db71), not #5059 (closed unmerged) - File header: notes that 0.51.8 to 0.51.9 and 0.51.11 to 0.51.14 were reserved by parallel branches and never released Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
Refs #4027, #4094, #4113, #4114, #4115, #4116, #3563, #3568, #4600, #4656 In-place changelog corrections: - 0.51.18: body replaced by a pointer; it repeated the 0.51.16 Fixed entry (released by #5159) and the 0.51.10 Changed entry (released by #5161) - 0.51.17: body replaced by a pointer; it repeated the 0.51.15 entry (released by #5156) - 0.51.7: states it shipped through #5154 (commit 9c2db71), not #5059 (closed unmerged) - File header: notes that 0.51.8 to 0.51.9 and 0.51.11 to 0.51.14 were reserved by parallel branches and never released Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
|
PR body contract — issue linkage This PR body conforms to the issue-linkage contract. Nothing to do. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
…a without volatile detail I21 and the audit effort-pin row named Opus 4.7 as the only non-high default and cited a first-run hold the model-config page no longer carries; both follow the 2026-09-28 read of the model-config and effort pages (Opus 5.5 and Sonnet 5.5 default to medium in Claude Code). The unhobble state-write gotcha and its eval stop restating block-hook-bypass exit code and heredoc coverage and defer to the hook. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Claude finished @kyle-sexton's task in 1m 46s —— View job Security reviewReviewed all 25 changed files ( No findings. This PR is documentation/skill-instructions and test-script maintenance for
Instruction-surface deletion lens applied: the diff removes/rewords several standing rules
Nothing in this PR touches |
|
Claude finished @kyle-sexton's task in 3m 10s —— View job Claude finished the code review
Review scopeThis is the CI code-review lane ( I focused on the code-bearing diffs, since the bulk of this PR (roughly 750 of ~840 added lines) is prose rewording in
I also cross-checked the rewritten prose in ResultNo findings meet this lane's bar. Nothing here is a correctness bug I could reproduce, and the two behavior changes with real logic risk (the |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5cb0e0dcdd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…llback permission-state.sh now marks a settings file invalid-json when permissions.defaultMode is not a string, with a test. The disable* keys stay with the C5-disableType lint, which reports a mistyped one. The audit-instructions 200000-token lane-window fallback carries its recheck trigger. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 6m 6s —— View job Claude finished the code review
Review scopeCI code-review lane ( The latest commit (
Findings (posted inline)
Everything else reviewed checked out: |
|
Claude finished @kyle-sexton's task in 3m 9s —— View job Security review
Reviewed the full diff against 1 finding, IMPORTANT, posted inline on The latest commit ( Other things checked, no findings:
|
…suites (#5316) Closes #3599 ## Summary Fixes from the 2026-09-29 audit of the Cursor agent's PRs that touch CI (group "ci"), one commit per change, all under `.github/`, `.gitleaksignore` and `scripts/gitleaks-*`: - Gitleaks: the local scoped-scan fork replaced the shared composite. The composite is re-pinned to v0.30.1 and the fork and its test are deleted (#3599). - Windows lane: the kindle-dedrm Pester step can fail; the exec-form launcher tests and two of the three remaining #3683 host-skip suites (markdown-format, cloud-bootstrap-plugins) now run on Windows (#3703, #3686, #3683). The third, audit_skill_visibility, fails on windows-2025 for a cause outside `.github/` and is dropped (#5323). - ci.yml: the UNMAPPED fallback runs the outside-node suites, the prerequisite-probe suite is wired, and the shell filter is widened (#3703, #4240, #4139). - Workflow comments point at their trackers instead of restating pins and remedies (#4130, #4670, #4144, #5323), and the gitleaks comment no longer implies a red dispatch. - test-linux installs hash-locked numpy and opencv so the animation suites run instead of skipping (#4594). - The silent-revert canary calls the shared base-ref predicate instead of its own copy (#3413). ## Fix - `aa6a6230d` `lint` job: `melodic-software/ci-workflows/.github/actions/gitleaks@35880dcb` (v0.30.1) with `scan-mode: git` and `log-opts` unset. A pull request scans its own commits (`<base>..HEAD`), a push scans main's full history, a dispatch scans every ref present in the clone. Only this step moves; the other composites stay at v0.27.1. `.gitleaksignore` keeps the two `04f4bcd5` fingerprints (reachable from main) and drops the five for commits no origin ref reaches. - `fafdab6af`, `bf21ed285`, `b748b5dd4`, `b2b689b52` `test-windows.yml`: the kindle-dedrm step fails the lane on a failing test; the launcher steps and the markdown-format and cloud-bootstrap suites run on `windows-2025`; the skill-visibility step added by `b748b5dd4` is dropped by `b2b689b52`. - `430e0d953` `ci.yml`: outside-node runner on the UNMAPPED fallback, `check-prerequisite-probes.test.sh` as a hard-failing `test-linux` step, wider shell filter. - `747b59154` comment-only changes in workflows. - `c2e18d24a` `.github/requirements-ci-animation.txt` (hash-locked) installed with `requirements-ci.txt` in one `--require-hashes` command, plus `ANIMATION_REQUIRE_DEPS=1`. The install stays (measured below). - `85ee97b36` comment-only: the gitleaks step comment says a manual dispatch scans every ref present in the clone; the `test-windows.yml` comment names #5323. - `dee4d13fa` `silent-revert-canary.yml`: "Resolve the pushed range" sources `scripts/lib/changed-files.sh` and calls `changed_files::verify_base` in place of the inline `git rev-parse --verify --quiet "<ref>^{commit}"`. The fallback (warn, scan the head commit) is unchanged. Applies the scripts group's request (c). - `2a619570a` `ci.yml`: the "Install locked plugin test toolchains" step diffs the `name==version` pins of `plugins/animation/requirements.txt` against `.github/requirements-ci-animation.txt` and fails when they differ (Codex review: Dependabot's `/.github` entry would bump only the CI copy). - Requests received from other groups: the animation, architecture, scripts (a, b) and claude-config requests were already met by the commits above or by issue operations; playbooks became a decision packet and hook-launcher was not triggered. Each outcome is under Related. ## Verification Static checks, on head `85ee97b36`: - `git merge origin/main` (earlier, into `5ca5fe296`): clean, no conflicts, none of its commits in the group's paths. - `actionlint` and online `zizmor --persona=regular`: no findings. - `bash scripts/check-lane-coverage.sh --check`: all 5 lanes reachable from `ci-status.needs`, 66 gate steps fed to the aggregator, 2 opted out. - `bash scripts/check-lane-coverage.test.sh`: PASS=40 FAIL=0. - `bash scripts/check-docs-only-gate.sh --check`: passes. - `bash scripts/check-changelog-parity.sh --check --check-order`: passes. - `bash scripts/validate-plugins.sh`: all manifests and the catalog validated. No plugin files changed, so no version bumps or changelog entries. On head `dee4d13fa`, which changes only `silent-revert-canary.yml`, re-run: `actionlint` over every workflow, `zizmor --offline --persona=regular` on the canary, `check-lane-coverage.sh --check` (66 gate steps fed, 2 opted out) and `check-shell-portability.sh origin/main`: all clean. The checks above were not re-run; the commit changes no other file. On head `2a619570a`, which changes only `ci.yml` (the pin check): equal pins pass and a one-sided `numpy` edit fails when the step's diff is run locally; `actionlint`, `zizmor --offline --persona=regular`, `check-lane-coverage.sh --check` (66 gate steps fed, 2 opted out), `check-lane-coverage.test.sh` (PASS=40), `check-docs-only-gate.sh --check` and `check-shell-portability.sh origin/main` are clean. The migrated step body was run in a scratch repository against five `before` values. A valid parent sha took range mode with no warning; 40 zeros, an empty value, an unknown sha and a non-ref each took commit mode with one warning. A dispatch of the canary on this branch, [36589890903](https://github.com/melodic-software/claude-code-plugins/actions/runs/36589890903) (head `dee4d13fa`), succeeded in every step; its empty `before` takes the commit-mode branch, so it proves the `source` line works on the runner and the scratch run covers the rest. #3599 acceptance criterion 1 (hygiene passes on a PR that does not touch `resolve-convention-home.sh`): met. This PR's own `lint` run, [36579146249](https://github.com/melodic-software/claude-code-plugins/actions/runs/36579146249) (head `5ca5fe296`, `pull_request`): "Scan for secrets" success, 8 commits scanned (`<base>..HEAD`), no leaks found. The run on the newest head `85ee97b36`, [36582778889](https://github.com/melodic-software/claude-code-plugins/actions/runs/36582778889), is green (`ci-status` success) and its scan of 20 commits found no leaks. The `ci` dispatch below, whose `--all` scan ran in a CI clone, scanned 3192 commits and also found no leaks, so a manual dispatch does not go red on other refs. The 8 findings a local all-refs scan reports come from local-only `refs/remotes/pr/*` refs that a CI clone does not hold (correction posted on #3599). Windows lane, two dispatches of `test-windows.yml` on this branch (the only run of these steps on a real Windows host): - [36528002813](https://github.com/melodic-software/claude-code-plugins/actions/runs/36528002813), red. Step "Test the skill-visibility audit on Windows" failed with 2 failures, both `AssertionError: 'unreadable' != 'read'`; the record was `bash exited 1 sourcing the lib: no stderr` for `plugins/claude-ops/lib/managed-scope.sh`. The cause is in a claude-ops script, not in `.github/`, so the step was dropped (`b2b689b52`) instead of committed red, and the defect is filed as #5323 (before this it lived only in the comment at `test-windows.yml:205`). - [36529242934](https://github.com/melodic-software/claude-code-plugins/actions/runs/36529242934), green, about 10.5 minutes (06:04:46 to 06:15:19) against `timeout-minutes: 20`, which stays unchanged. Per step: - kindle-dedrm Pester (`Run.Exit` set): 11 passed, 0 failed, 0 skipped. - markdown-format: PASS=168 FAIL=0 SKIPPED=4. The host probe fired: four counted `SKIP (host: cygpath rewrites ...)` lines, plus the uncounted symlink-escape skip. - cloud-bootstrap-plugins: PASS=79 FAIL=0, no probe skip; the stubbed `claude` ran on Git Bash. - exec-form launcher, resolver test (`node --test lib/exec-bash.resolver.test.mjs`): 1 pass, 0 fail. - exec-form launcher, `plugins/guardrails/hooks/exec-bash.test.sh`: passed (stdin, exit 2, Git Bash resolution, hooks.json shape, 8 dispatcher rows). `ci` dispatch [36577675603](https://github.com/melodic-software/claude-code-plugins/actions/runs/36577675603) (head `c2e18d24a`), which measures the animation install and the gitleaks step: - `lint` success; "Scan for secrets" scanned 3192 commits, no leaks found. - `test-linux` legs 0, 1 and 3 green. Leg 2 red only on `plugins/planning/tests/interview-defenses.test.sh` (`SKILL.md frontmatter is unchanged` digest check). That is outside this group's paths and the suite failed the same way at the branch's base; a snapshot of origin/main `9ef496019` passes it (PASS=154 FAIL=0), so the next base merge clears it. - `Install locked plugin test toolchains`: 11 to 14 s per leg with the animation wheels, against 6 to 8 s per leg on today's main push runs 36580419086 and 36580578535 (one 15 s sample). Leg wall time: 162 to 281 s against 141 to 288 s on those runs, so the install adds about 5 s and the wall-time spread is main's own run-to-run spread. No leg is more than 60 s slower, so the install stays, and the animation group's `ANIMATION_REQUIRE_DEPS=1` request stands. ## Related - Audit report: `.work/audit/REPORT.md` findings for #3599, #3703, #3686, #3683, #4240, #4139, #4130, #4670, #4144, #4594. - Refs #3703, #3686, #3683, #4240, #4139, #4130, #4670, #4144, #4594, #5323, #3413 (the owning groups finish those). - Decision packet for the owner: #5333 (a PR body that says the merge-hold phrase holds nothing; options A to D, nothing implemented). - Requests received from other groups, checked against origin/main `f2f421f7b`: - playbooks (a merge-hold guard for the #5154 failure): not implemented, decision packet #5333. The label is the convention's only hold, the reading step is in the ci-workflows composite, a `GITHUB_TOKEN` label does not re-run `ci-status`, and the phrase appears in 63 PR bodies (22 merged). The lane half went to source-control. - hook-launcher (test-windows steps after the probe): not triggered. No claude-ops re-land PR is open; the YAML-reader and probe steps are byte-identical to origin/main and the launcher steps here follow them. - architecture (five dead `.gitleaksignore` lines): already applied in `aa6a6230d`; both commits are unreachable from origin/main. - tracker (#4670): already applied. #4670 is reopened with operator steps; the ci-workflows issue is operator step 3, so none was filed. - animation (hash-locked numpy and opencv, `ANIMATION_REQUIRE_DEPS=1`): already applied in `c2e18d24a`, measured above. - scripts (a) the prerequisite-probe suite: already applied in `430e0d953` as a hard-failing step like its four `scripts/lib` neighbours; without `continue-on-error` the lane-coverage gate would report an unfed gate, and it passes. (b) #3413: already commented, follow-up #5321. (c) the canary predicate: applied in `dee4d13fa`. - claude-config (#4094): already applied. #4094 is open and its comment names #5311 (`Refs: #4094`, unmerged draft) for items 5, 6, 8, 9 and 10 to 12. - Cross-group requests sent: core-docs (docs/ci-runner-routing.md time-to-green job list and contract-only remedy wording), conventions (token-leak-amplification suite, two rationale edits), scripts (gate-entry.test.sh guard, verb-contract gate test, then a ci.yml self-test step in a second pass), guardrails (#4527; #3683: this PR adds two of the three remaining host-skip suites, markdown-format and cloud-bootstrap-plugins, so read their Windows results above; audit_skill_visibility did not land), claude-ops (#5323: managed-scope.sh under Git Bash on windows-2025, plus restoring the dropped test-windows step when fixed), hook-launcher (#3708 and backslash-root case), animation (`ANIMATION_REQUIRE_DEPS` must exit 1 instead of skipping), playbooks (hygiene.md residue-dissolve note), claude-config (#4094). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…eAutoMode, find the I33 hub from a subdirectory Revert the defaultMode type gate in permission-state.sh: it made a file with a malformed defaultMode invalid-json, which skipped emit_file_conf and dropped the mistyped disableAutoMode the C5-disableType lint reads. A test now covers both defects in one file. hub_of() in emit-findings.sh probed repo-relative paths from the caller's directory, so a relative path from a subdirectory never found the hub. It now probes from the repository root, with a test that fails without the change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 2m 13s —— View job Security review
No findings. This is a re-review at HEAD
No new security-relevant issues in the rest of the diff ( One remaining open item, not a security finding: |
|
Claude finished @kyle-sexton's task in 2m 10s —— View job Claude finished the code review
Review scopeCI code-review lane ( Verified fixes
Both fixes are consistent with the existing pattern elsewhere in the file ( Not re-flaggedThe third open comment ( Not verifiedI could not execute the test suites in this environment (bash tool execution was denied by the sandbox), so the above is verified by code trace only, not by running No findings. |
Refs: #3563
Refs: #3568
Refs: #4027
Refs: #4094
Refs: #4113
Refs: #4114
Refs: #4115
Refs: #4116
Refs: #4583
Refs: #4600
Refs: #4656
Summary
Fixes the
plugins/claude-configfindings from the audit of the unattended Cursor PR run. Every change is insideplugins/claude-config/;hooks/exec-bash.mjsis untouched.audit-instructions: the findings relay now followscriteria.md(I31 and I33 surfaces, I32 tier by arm),finding-ids.shrefuses non-instruction files under$HOME,SKILL.mdrecords the subagent-window claim and the I33 dispatch rule, andexecution-and-report.md(a second home for facts other files own) is deleted.unhobble: delivers the claude-config/unhobble: durable state, gate-aware strip plan, sourced carve-out, decide composition #4094 must-fix items (product-surface class, session branch, convention oracle test,readdrefusal) and nice-to-have items (statusfields, ledger grouping,decide), and removes silence as a deletion warrant (claude-config: design per-rule deletion-evidence attribution for unhobble's ledger grammar #3563).audit-permission-state: independent review of the chore: apply changelog rows for CLI surfaces and managed connectors (#4027) #5154defaultModelint, which reached main under a "Do not merge" body with no review.audit: the live-hook ask row carries the unattended-lane note (claude-config audit: baseline push ask rule contradicts a repo's declared autonomous merge lane #4600).conflict-criteria.mdloses its dead repo-root link (docs: decide ownership for shared-surface instruction governance #3568).README.mdandCHANGELOG.mdare corrected; version 0.52.0.Fix
conflict-criteria.mdused six../segments that resolved outside the repository, and an installed plugin does not carrydocs/. It now names the path in code font.emit-findings.shadmits I31 in any skill-directory file and I33 in any skill-loaded file exceptSKILL.md, names the nearest ancestorSKILL.mdas the I33 hub, and tiers I32 CRITICAL underplugins/and IMPORTANT elsewhere. The persist-admission text incriteria.mdandpersist-findings.mdnames the scanner (I28, I29) and lane (I30 to I33) intakes.finding-ids.shsurface_of()(audit-instructions: adopt (check, claim, sites) finding identity and admit I30 to I33 to --persist-findings #4116, the security-lane finding left open at merge of feat(claude-config): stable audit-instructions finding identity (#4116) #4851): the user surface stays home-wide, and now admits only instruction-file shapes. Basis: Claude Code readsCLAUDE.md,CLAUDE.local.mdandAGENTS.mdfrom the working directory and every directory above it, and follows imports to absolute paths, so narrowing to${CLAUDE_CONFIG_DIR:-$HOME/.claude}would drop real user surfaces. Any markdown file,settings.json,settings.local.jsonandhooks.jsoninside a.claudetree or the resolvedCLAUDE_CONFIG_DIR, and files beneath askills/directory in those trees are admitted;~/.ssh/config, credentials, transcripts and dotfiles are refused assurface-not-an-instruction-file. The scope carries its four-part verification record in the code. This is the citation for dismissing the open PR-comment finding on feat(claude-config): stable audit-instructions finding identity (#4116) #4851.relativize_in_repois unchanged.audit-instructionsdocs (claude-config: audit-instructions execution model, scanner calibration, report contract, and environment fit #4113, audit-instructions: token-budgeted lanes, --unattended, and --resume over per-lane run files #4114, audit-instructions: I6 pre-scan adopts the audit-noise gate set; I33 lane fences, excerpt anchors, and per-plugin presentation #4115, fix(claude-config): finish audit-instructions catalog gaps and dispatch plan #4656): lane sizing loses its ticket back-references, the subagent-window claim gets a four-part record, the read-only contract covers lane reports and run-state writes, I33 rows count as one dispatch outside per-lane verifier batches, andSKILL.mdregains line headroom under the 500-line cap.audit-engine.sh(claude-config audit: baseline push ask rule contradicts a repo's declared autonomous merge lane #4600): theHOOKS_LIVE=1row ends with$lane_note, like the other ask-rule rows.unhobble(claude-config/unhobble: durable state, gate-aware strip plan, sourced carve-out, decide composition #4094, claude-config: design per-rule deletion-evidence attribution for unhobble's ledger grammar #3563): the one-row watch disqualifier versus the two-row re-add grammar is this skill's own rule (SKILL.mdPhase 4 step 1), not an upstream one.SKILL.mdandevals/evals.json(evals 27 to 30 added; 18 and 22 tightened). Items 1 to 4 and 7 of claude-config/unhobble: durable state, gate-aware strip plan, sourced carve-out, decide composition #4094 were already on main (feat(claude-config): keep unhobble experiment state in the repo (#4094) #5081). Items 5, 6, 8, 9 and 10 to 12 land here.permission-state.shclassified a settings fileinvalid-jsonwhen the last key underpermissionswas a string, becausejq -ereads only the last output of a per-key check, soC2-defaultModeandC5-disableTypecould not fire on real files. Fixed with tests that fail against the old reader. The masking claim now carries its condition, and the unsourced auto version boundary is removed. Claims were checked against pages fetched 2026-09-29 (recorded in the commit body).CHANGELOG.md(Apply the Claude Code 2.1.257 to 2.1.263 changelog decisions: 20 corrections, 1 native nomination, 7 adoptions, 3 declines #4027): the repeated 0.51.17 and 0.51.18 bodies became pointers, 0.51.7 records that it shipped through chore: apply changelog rows for CLI surfaces and managed connectors (#4027) #5154, and the header notes the unreleased reserved versions.criteria.mdI21 and theauditeffort-pin row state the effort defaults from the model-config resolution order fetched 2026-09-28 (Opus 5.5 and Sonnet 5.5 default tomedium, Opus 4.7 toxhigh; the first-run-hold clause is gone), with Verified, Source and the recheck trigger restamped.unhobbleSKILL.mdand eval 15 stop restating theblock-hook-bypassexit code and heredoc coverage and defer to the hook.In-place changelog corrections:
No issue is closed by this PR. #4094 stays on
Refsbecause its 14-item checklist is not verified complete here, and the others are decision-held or have leftovers in other groups.Verification
Run in
/home/kyle/worktrees/ccp-fix-claude-configafter mergingorigin/main(aebb9bb):plugins/claude-config/**/*.test.shsuites: exit 0 (includesemit-findings.test.sh,finding-ids.test.sh,finding-identity.test.sh,permission-plane-lint.test.sh,permission-state.test.sh,audit-engine.test.sh,lane-runs.test.sh,instruction-files.test.sh).bash scripts/check-detector-findings-crosswalk.sh --check: OK, 38 rule rows.bash scripts/check-changed-skills.sh origin/main: 4 skills checked, 0 failed.bash scripts/check-changelog-parity.sh --check --check-order,--check-bump origin/main,--check-preserved origin/main(190 headings compared): pass.bash scripts/validate-plugins.sh: all manifests and the catalog validated.shellcheckon every changed.shfile (the SC2016 hit on theemit-findings.test.shrule fixture line is suppressed with a reason) andcheck-evals-quality.shon the changed evals pass;check-skill.shwarnings that remain were present on main.#5154 review outcome (#4027):
defaultModemasking claim, thepermissionskey shapes the lint reads, and the auto-mode version boundary, each against Claude Code docs pages fetched 2026-09-29.permission-state.shreproduced theinvalid-jsonmisclassification when the lastpermissionskey was a string.jq -echeck counted only the last output, soC2-defaultModeandC5-disableTypecould not fire on real files. New tests inpermission-state.test.shfail against the old reader and pass now.Related
Audit report:
.work/audit/REPORT.mdfindings by issue number: #3563, #3568 (row 3c), #4027 (3b), #4094 (3b), #4113 (3b), #4114, #4115, #4116, #4583, #4600, #4656 (3c).Cross-group requests (not done here):
docs/plugin-philosophy.mdName one owner for the hardcoded-consumer-specifics doctrine #4583 structure and citation defects, thedocs/upstream/claude-code.mdledger re-point from fix(claude-config): flag project defaultMode bypassPermissions as dead (Refs #4027) #5059 to chore: apply changelog rows for CLI surfaces and managed connectors (#4027) #5154, fix(claude-config): apply 2.1.257–2.1.263 permission changelog corrections (#4027) #5159 and feat: adopt Claude Code 2.1.257–2.1.263 changelog capabilities (#4027) #5161, the row 257-089 status, the FORCE decline reconciliation, and review of the chore: apply changelog rows for CLI surfaces and managed connectors (#4027) #5154 philosophy changes.check-changelog-parity.shshould reject a CHANGELOG entry whose body is byte-identical to an earlier entry.docs/conventions/detector-findings/README.mdcrosswalk rows for I31, I32 and I33 restate the surface set and the I32 tier ascriteria.mddefines them.Cross-group requests received and not applied here:
docs/upstream/claude-code.mdand already edits that row.Issue operations done: #4027 and #4115 reopened with decision packets, packets on #3568 and #4027 extended, comments on #4113, #4116, #4656, #4583 and #3563.
🤖 Generated with Claude Code
https://claude.ai/code/session_01EugXnFddtpHcY5gTuyEirB