feat(claude-config): add the cross-surface instruction-conflict checks and an OPINION tier - #1316
Conversation
…on-audit catalog Two new checks and three edits to existing ones, per the proportionality gate's D1-D4 and D6 dispositions. I12 (cross-surface instruction conflict) detects two live instructions that cannot both be satisfied where no official layering rule already picks a winner. It is scoped by routing around the incumbent rather than duplicating it: claude-memory:audit C6 already reviews contradictions inside the memory layer, so a contradiction wholly inside that layer is C6's and I12 does not report it. A contradiction with a side outside the memory layer, or any side in the managed-policy tier, is I12's. Remediation splits by scope and never defaults to deletion. Findings are pairwise and name both participating locations. I13 (definition-site locality) is a different axis from I3: I3 is load timing, I13 is locality, and an instruction can be correctly deferred and still misplaced. OPINION-tier and off by default. The stopping condition on I6 and I8 withholds trim proposals against high-consequence areas. It is OPINION-tier but enabled by default, because a suppressor defaulted off deletes the only bound those two checks have. The catalog gains the OPINION enablement policy the tier never had, and YAML frontmatter carrying version 1.1.0 in place of the body-prose line. I3's remediation now qualifies its destination (@path imports do not defer) and prices the move; I9's names the interface destination. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…in C3 One consolidated revision to check C3 (Content Placement), not three checks: the rows answer one question, so separate filing would emit three findings on one misplaced section. The destination set predated auto memory as a destination - the plugin audits it as a first-class entity in M1-M4 but never routed content to it. It now carries a row, stating that Claude writes it and that asking Claude to remember something lands there rather than in CLAUDE.md. @path imports are named as a non-destination: imported files load at launch, so a split into imports reorganizes and saves nothing, and the same holds for an import inside a path-scoped rule. Every move recommendation is now priced against the compaction table in reference/official-guidance.md. Both facts were already recorded in that file and no check cited them. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…irical claim Three corrections from review of the I12/C3 landing. I12's comparison set is now resolved before it is compared: @path imports expanded and symlinks followed. Imported files load at launch, so a detector reading only the importing file compares a different surface than the model sees, and every @docs/foo.md import would be invisible to it. AGENTS.md is affirmatively excluded with the reason recorded - Claude Code reads CLAUDE.md, not AGENTS.md, so a stock install never loads one and flagging it would false-positive on repos that keep one for other tools; its content enters only through an import. C3's import-inside-a-path-scoped-rule clause was the only claim in either catalog resting on a first-party repro rather than a cited page. It moves out of the routing table into a provenance-marked paragraph, following RD1's idiom, so the update action cannot overwrite it with doc-sourced text and its recheck trigger is a re-run rather than a doc re-fetch. Adds the audit-instructions eval that was missing for I3's tightened destination rule - the edit changed remediation behavior with no case exercising it. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Claude encountered an error after 0s —— View job I'll analyze this and get back to you. |
|
Claude encountered an error after 0s —— View job I'll analyze this and get back to you. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a5ce478453
ℹ️ 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".
…1318 ship Task #21, walked against the gate's own body in MIGRATION-PLAYBOOK.md rather than against this plan's seven-word summary of it, and against the two PRs' shipped files rather than their descriptions. Recording a pass on a criterion nobody substantiated would have been the same read-the-incumbent's-body failure this effort keeps recording, applied to the gate itself. One criterion fails. Security-review criterion 4 forbids ../ reach-outs, and audit-pass carries three — SKILL.md:163, run-contract.md:104, and exclusion-set.md:72 — all pointing at docs/conventions/finding-suppression, which #1318 creates at the repository root. Each resolves in this repository and to nothing in an installed plugin. That is this plan's own horizontal-decoupling grounding finding landing on the artifact it was written to protect, and the playbook lists it first under the caveats that break a working in-repo skill. The convention document is the right home for the keys; the pointer is what has to change. One criterion cannot close. The plugin-acceptance security review still owes an adversarial injection fixture corpus and verification that the exclusion-set derivation is not itself an injection target. Its hook, MCP, telemetry, provenance, and PATH surfaces are all clean — audit-pass ships none of them — so the residual is entirely the runtime behavior the threat model covers. Five criteria pass with evidence. Repo-agnosticism is real rather than assumed: the exclusion set derives every class and names the empty case for a target with no registry, and there are zero hardcoded repo or machine identifiers. No userConfig is the correct answer rather than an omission, because the ownership table assigns by kind and audit-pass has no personal-or-administrator scalar. Two divergences from this branch's design are recorded as findings against the implementation lane. The shipped run-contract carries the superseded (surface, check, anchor, claim) tuple, which cannot express the pairwise finding D1 exists to produce, and has no liveness-basis concept at all — so Assertion 1.1 ships unscoped and P1 ships without its liveness clause. Neither is a gate criterion; both would make the shipped contract fail its own idempotence claim. The no-PII pass is today's, with the hazard named forward: when the liveness basis lands it must take the scope-prefixed form surface already takes, or a report that may be redirected into the target tree carries the operator's home path. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… skill Both catalogs recommend moving only-sometimes-relevant content to a skill, and both priced that move only against compaction. That undercounts it. A skill's body defers, but its listing entry does not: skill descriptions are loaded into context so Claude knows what is available, and the combined `description` and `when_to_use` text is truncated at 1,536 characters in the listing to bound that cost. So "move it to a skill" moves part of the cost into the always-loaded tier rather than out of it, and a remediation that omits the entry reports a saving larger than the one it delivers. The cost is charged only where it is real. A new skill adds an entry; a move into a skill that already exists adds none, and pricing that case would overstate the cost in exactly the way this fix exists to prevent. The one field that keeps a description out of context is `disable-model-invocation: true`, which also makes the skill user-invocable only — named with its consequence, since recommending it silently is the capability change the compaction clause already refuses. `user-invocable: false` does not remove the description, and `skillOverrides` does not reach plugin skills, so neither is an out. Stated as a cost on the recommendation, not as a Detect clause or a threshold: whether a corpus is over its listing budget is a separate check and a separate work item. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 3m 27s —— View job PR Review — feat(claude-config): cross-surface conflict checks and OPINION tier
SummaryThe design is sound: the routing convention, OPINION-tier policy, stopping condition, and import-expansion requirement are all well-reasoned. Three findings below, in descending severity — two confirm Codex's P1/P2, and one is new. Finding 1 — C6 scope gap invalidates I12's routing for nested and user-scope CLAUDE.md (confirmed P1)Severity: Moderate I12's routing rule says: "A contradiction wholly inside the memory layer… is C6's." But C6's actual discovery (in
I12's comparison set explicitly includes "CLAUDE.md at every scope — managed policy, user, project root, nested, CLAUDE.local.md." So a contradiction between The fix is either: (a) expand C6's Step 1 discovery to include all nested CLAUDE.md files and user-scope CLAUDE.md before the cross-reference step, or (b) tighten I12's routing to delegate to C6 only for "project-root CLAUDE.md, CLAUDE.local.md, and project rules" contradictions, retaining nested and user-scope conflicts as I12's responsibility. Option (b) is lower-risk since it doesn't require changing the incumbent skill. Finding 2 — Eval ID 8 conflict pair can be satisfied simultaneously (confirms Codex P2)Severity: Low
These can both be satisfied — you can update a README without adding code comments. Per I12's own threshold, a finding requires "two live instructions that cannot both be satisfied." This example doesn't clear that bar. The eval trains the skill toward a false positive in exactly the case I12 explicitly says not to flag. A genuinely incompatible replacement:
These cannot coexist — one demands inline comments, the other forbids them. Finding 3 — I12's
|
|
Claude finished @kyle-sexton's task in 2m 18s —— View job Security Review
Scope reviewed: all 9 files changed in this PR (plugin manifests, changelogs, SKILL.md, criteria.md, evals.json for both plugins). Scripts ( No security vulnerabilities foundThis PR is entirely prose and configuration — audit criteria text, eval definitions, and version bumps. No new shell execution paths, no workflow files, no external dependencies, no secrets handling, and no GitHub Actions patterns were introduced. The relevant security properties of the existing system are preserved and, in several places, explicitly reinforced by the new criteria text. Specific checks:
I12 managed-policy handling is correct. The new check reads managed-policy CLAUDE.md for conflict detection but the criteria explicitly prohibit proposing any edit to that tier — neither to the policy side nor to the consumer side on the strength of the conflict alone. The remediation section correctly routes this as an organizational decision. Symlink resolution scope (I12's "resolve symlinks before comparing") mirrors what Claude Code itself does at session launch, so no new attack surface is opened. The audit reads whatever surfaces Claude Code would load; it produces a local-only report with no exfiltration path.
Report-only contract is maintained and strengthened. SKILL.md continues to state no |
… moved The proportionality pass downgraded the state key's repo-identity half and deferred per-lane input digests, but only the gate document said so. The re-run contract still presented both as settled, unqualified — which re-created the same two-documents-disagree defect the pass was closing. Fixed at the contract end, pointing at the gate's reasoning rather than restating it. Assertion 5.2 is now explicitly owed only under the per-lane form. Assertion 5.1 holds under both, because a tree-wide refuse-to-resume check closes the P1 hole just as completely; what per-lane digests buy is partial resume, and its value is unmeasured until Phase 10 has lane costs. Also records a cross-PR semver collision the acceptance-gate walk surfaced. #1316 and #1318 both take claude-config from 0.9.2 to 0.10.0. Each passes changelog-parity on its own branch; the pair does not, and the second to merge lands a version already claimed with a duplicate changelog heading. Invisible from either branch and surfacing only at the second merge, so it is recorded where both lanes can see it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 78aac8351c
ℹ️ 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".
… changed The previous commit added doc-sourced content to both catalogs — the skill listing entry's cost, quoted from a page neither catalog had cited before — and left the date stamps reading 2026-07-24. Under either reading of the field, last edited or last reconciled against official docs, both were wrong the moment that commit landed. A staleness stamp that its own edits do not move is worse than none: it reports a recheck that did not happen. The catalog versions stay at 1.1.0 and 1.3.0 because neither has shipped — the plugin manifests carrying them are unreleased on this branch, so the listing-entry change is part of the same revision, not a successor to it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 3m 50s —— View job PR Review — feat(claude-config): cross-surface conflict checks and OPINION tier
New commit (1d6e446) — cleanThe commit corrects date stamps in both criteria catalogs from Outstanding findings — all carry forward from the earlier review passNone of the prior findings were addressed in commits Finding A — Eval 2 expectation is stale:
|
|
Claude finished @kyle-sexton's task in 1m 25s —— View job Security Review — PR #1316
Scope: 9 changed files — two No security vulnerabilities found. This PR is entirely prose and configuration. Specific checks:
I12 managed-policy and import-expansion handling — no new attack surface. I12 instructs Claude to read managed-policy CLAUDE.md files for conflict detection, but the criteria explicitly prohibit proposing any edit to that tier. The |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1d6e4462fc
ℹ️ 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".
… published URL `audit-permission-grants` reached the permission-rule-hygiene convention through a `../` relative link, in both `SKILL.md` and `reference/criteria.md`. An installed plugin runs from an isolated cache containing only the plugin's own tree, so the link normalized to a path above the cache root and resolved to nothing. The skill directed a read that cannot succeed in installed form. It survived because it resolves in a full-repo checkout, which is the shape every author sees. Verified against the live cache rather than on paper: the installed root holds `.claude-plugin`, `.in_use`, `skills`, `CHANGELOG.md`, and `README.md` — no `docs/` — and the normalized target does not exist. The convention's published URL is the fix, not a copy. Hand-copying the principle, the three anti-patterns, and the correct pattern into the plugin would create a second owner for rules the convention already owns and guarantee drift. The URL form is what sibling plugins already use for marketplace conventions, and it resolves from the isolated cache, which a repo-relative path cannot. Nothing about a run depended on the reach-out: each check's Recommend line already carries the fix in the form the report needs. Both files now say so, so the convention is named as the doctrine's owner rather than implied to be a runtime dependency. The reference file carried the same defect as the skill body and is fixed with it. A sweep scoped to skill bodies and agent definitions does not reach a skill's own reference tree, and one instruction surface fixed while its sibling still points nowhere is not a fix. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 2m 13s —— View job PR Review — feat(claude-config): cross-surface conflict checks and OPINION tier
New commit (ae01bc7) — cleanThe commit replaces Outstanding findings — none have been addressed since the prior reviewFive findings from the second review pass carry forward unchanged. Summarized below; the prior review thread has the full detail and permalink anchors. Finding A — Eval 2
|
|
Claude finished @kyle-sexton's task in 2m 6s —— View job Security Review — PR #1316
Scope: all 11 changed files — two No security vulnerabilities found. This PR is entirely prose and configuration. Specific checks:
I12 import-expansion and symlink-resolution — no new attack surface. I12 instructs Claude to expand Managed-policy handling is correct. I12's criteria explicitly prohibit proposing any edit to the managed-policy tier, and the remediation block adds an explicit "never a default deletion" guard for both sides of any conflict. No write path to a managed surface exists.
Unpinned raw GitHub URL — noted, not a vulnerability. Report-only contract maintained. SKILL.md continues to state no |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ae01bc7c11
ℹ️ 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".
…ctions Address the Codex review threads on the cross-surface conflict check: - Cede memory-layer conflicts to claude-memory C6 only for the surfaces C6 actually discovers; user-scope and nested memory conflicts stay in I12. - Inventory managed policy and out-of-scope I12 counterparts read-only in Phase A, and extract prompt-hook text from .claude/settings.local.json. - Run I12 in one dedicated cross-surface lane instead of per-surface lanes. - Drop MCP servers from the shadowed-definition report; nothing inventories MCP configuration here. - Add a no-change report representation so the managed-policy no-edit rule no longer contradicts the per-finding diff contract. - Filter the comparison set by co-activation; correct the disjoint-scope exemption to two conditional instructions. - Constrain I13 move destinations to surfaces Claude loads. - Fix the stale I6-I11 eval strings and replace the co-satisfiable pair in the conflict eval. - Correct the claude-memory guidance snapshot that claimed Claude Code loads AGENTS.md, per https://code.claude.com/docs/en/memory
|
Claude finished @kyle-sexton's task in 3m 31s —— View job PR Review — feat(claude-config): cross-surface conflict checks and OPINION tier
New commit (45b88fe) — substantive, closes four of five outstanding findingsThe commit addresses the bulk of the open review thread: C6 routing tightened, cross-surface conflict lane added, co-activation filter, disjoint-scope exemption corrected, no-change representation for managed-policy findings, I13 destination constrained to loaded surfaces, MCP servers dropped from the shadow report, managed policy and out-of-scope counterparts inventoried read-only, local-settings hooks included, eval strings updated, and the official-guidance snapshot corrected. The scope-filter logic ("narrows which side may produce findings, not which are read") is cleanly stated and handles the scoped-invocation gap that Codex flagged. Findings closed since the prior review pass
One finding remains openFinding D — I12's
|
|
Claude finished @kyle-sexton's task in 2m 15s —— View job Security Review — PR #1316
Scope: 12 changed files — two No critical or important security vulnerabilities found. This PR is entirely prose and configuration. Specific checks:
SUGGESTION — Unversioned raw.githubusercontent.com URL (confidence: high; not a current vulnerability)File: The criteria file references the permission-rule-hygiene convention at: This URL is pinned to The risk materializes only if the URL is ever promoted to a runtime fetch. If that happens, main-branch content could be changed between skill invocations, injecting different "recommended" text into the audit report without a version gate. The mitigation for that future path is to pin to a commit SHA rather than Report-only contract maintained and strengthened. SKILL.md continues to state no
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 45b88fe4c2
ℹ️ 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".
…s and plugin cache Managed-settings prompt hooks and live upstream-owned instruction text (plugin-cache skill bodies and agent definitions, managed materializations) can hold one side of a cross-surface conflict, so Phase A now reads them for comparison. Ownership is unchanged: they propose nothing and route upstream.
|
Claude finished @kyle-sexton's task in 3m 23s —— View job Security Review — PR #1316
Scope: 12 changed files — two Prior security reviews covered commits through No critical or important security vulnerabilities found. Surface-by-surface checks
New in
|
Four review findings on the cross-surface conflict pass. The pass received Phase A's filesystem inventory and read presence in the tree as liveness. Liveness is a session property: the launch directory picks which ancestors are candidates, claudeMdExcludes merges across every settings layer, omitting project from --setting-sources skips project rules, and --add-dir with CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD adds live memory files no tree walk sees. Phase A now resolves those controls; what it cannot resolve is marked liveness-unresolved rather than graded. A prompt-type hook's text goes to a separate evaluator model and never enters this session's context, so comparing that prose manufactured conflicts between two models that each satisfy their own instructions. The hook now enters the comparison set as the act it gates under its event and matcher. That also closes the UNVERIFIED residency row. Eval 13 rewarded saying an @path in an agent definition loads at launch, which the catalog's own I13 contradicts; it now requires the reason that applies. The claude-memory C3 eval left the CLAUDE.md remainder unspecified while demanding it be moved. The prompt now says what the remainder is, and the expectation requires the destination to be justified by relevance rather than by the line budget.
|
Claude finished @kyle-sexton's task in 3m 58s —— View job PR Review — feat(claude-config): cross-surface conflict checks and OPINION tier
New commit (4edbe90) — closes all four open Codex P2s and Finding DThe commit closes every outstanding item from the prior review pass. Finding D — closed in 4edbe90
This resolves the Phase C framing mismatch via option (b) — the refutation questions map directly to gates 2, 4, and 5, giving a verifier a coherent frame for a conflict pair rather than the removal question. The Four Codex P2s closed since the prior review pass
New content evaluated — no issues foundLiveness section in Hook-as-gate section: The treatment is correct and the worked example is genuine. The "A prompt hook's text is not an instruction to the main session" heading correctly anchors the scope of what enters the comparison set (the gate) versus what doesn't (the evaluator's prose).
Eval 13 distinction ( All prior findings — remain closed
Version consistency — correct
No issues found. The PR is clean. |
|
Claude finished @kyle-sexton's task in 3m 38s —— View job Security Review — PR #1316
Scope: 14 changed files — two No critical or important security vulnerabilities found. This PR is entirely prose and configuration — audit criteria text, eval definitions, conflict adjudication rules, and version bumps. Specific checks:
Secret handling — strengthened by latest commit (4edbe90)
The latest commit tightened hook text handling: the hook enters the comparison set as the constraint it imposes (which act it gates + its event/matcher conditions), not its raw prose. This correctly prevents evaluator-directed content — including format directives, personas, or output-format instructions the evaluator's prompt contains — from reaching the conflict comparison. A prior incarnation would have compared that raw prose against main-session instructions, which could have pulled sensitive evaluator configuration into the audit report. The current formulation closes that gap cleanly. The "prompt text only and no secret-bearing values" constraint also applies to the upstream-owned plugin Managed-policy reads — no write pathOrg-managed policy Liveness resolution — correct direction for securityThe latest commit adds a liveness-resolution requirement: Phase A must resolve Plugin cache reading — enablement-gated, version-resolvedPlugin skill bodies and agent definitions are inventoried only from the cache of a plugin whose effective SUGGESTION (carry-forward from prior reviews) — unversioned raw.githubusercontent.com URLConfidence: high · Not a current vulnerability
This URL is pinned to This file is unchanged in this PR; the observation carries from prior security review passes. Report-only contract maintained. SKILL.md states no |
Merge with
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4edbe90ad2
ℹ️ 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".
…t style Three review findings, all coverage gaps in the conflict pass's corpus. Auto memory was excluded outright for routing, but conflict-criteria.md assigns every pair involving it to I15 precisely because claude-memory's C6 does not read MEMORY.md — so a MEMORY.md-versus-CLAUDE.md contradiction was audited by neither skill. It now enters the read-only tier, loaded content only. A plugin can ship an output style, and one with force-for-plugin applies whenever the plugin is enabled, overriding the user's outputStyle. The user/project scans cannot reach the plugin cache, so the active style could be missing from the corpus entirely. Phase A now resolves which style is actually active and inventories that one. Eval 7 expected memory-layer contradictions to be reported unchecked when claude-memory is absent, contradicting the fallback contract that keeps the pair as an I15 finding. The routing avoids duplicate findings; it does not drop the only one.
|
Claude finished @kyle-sexton's task in 2m 20s —— View job PR Review — feat(claude-config): add the cross-surface instruction-conflict checks and an OPINION tier
New commit (52d3eaf) — closes all three Codex P2s from the prior roundThe commit addresses the three P2s Codex raised on Three Codex P2 findings closed since the prior review pass
New content evaluated — no issues foundAuto-memory bullet placement: Correctly placed in the read-only tier (after the editable exclusion clause for auto memory at line 121). The two are not contradictory: the editable exclusion removes it from the proposal set; the read-only bullet adds it to the comparison set. Both are required for I15 to work. Output-style resolution logic: The Eval 7 first expectation precision: The expectation now says "root-level project memory surfaces" (rather than just "memory surfaces"), which correctly narrows to C6's actual population per the boundary table in CHANGELOG entry: Accurate. The three fixes are narrated correctly and the routing-vs-dropping distinction is cleanly stated. All prior findings — remain closed
No issues found. The PR is clean. |
|
Claude finished @kyle-sexton's task in 3m 28s —— View job Security Review — PR #1316
Scope: 14 changed files — two No critical or important security vulnerabilities found. This PR is entirely prose and configuration. Specific checks:
Secret handling — new
|
There was a problem hiding this comment.
💡 Codex Review
Fresh evidence after the earlier import-expansion thread is the surviving blanket instruction here: when an agent or skill body contains @path, I13 itself says the syntax is inert on those surfaces (criteria.md:275-280), but this rule still directs I15 to resolve it before pairing. That can make an unread reference file appear resident and produce a false conflict, so expand imports only for the CLAUDE.md-family surfaces that implement them.
ℹ️ 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".
…eval 8 Auto memory is on by default, but autoMemoryEnabled: false at any settings scope or CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 turns it off, and a MEMORY.md left on disk from before is then neither loaded nor written. Phase A resolves that state before inventorying the file — the same gate the plugin-cache surfaces carry, for the same reason. Eval 8 asked the run to say which side to change for a skill body against a CLAUDE.md, which the precedence table classifies as unresolved: the skills page states no authority relation between the two, and silence is not a winner. The eval now requires an unresolved verdict with both anchors quoted and the choice left to the operator.
|
Claude finished @kyle-sexton's task in 3m 17s —— View job PR Review — feat(claude-config): add the cross-surface instruction-conflict checks and an OPINION tier
New commit (3714d36) — closes two of three Codex P2s from the prior roundThe commit addresses two of the three P2s Codex raised on Two Codex P2 findings closed
One finding remains openCodex P2 — Import expansion still applies blanket to all surfaces (criteria.md:352–354, not addressed in 3714d36)
This is a blanket instruction with no surface restriction. I13 ( If Phase B2 applies the blanket expansion rule to a skill body that contains The fix is a one-line qualification: "Resolve Items confirmed no-issue
|
|
Claude finished @kyle-sexton's task in 2m 29s —— View job Security Review — PR #1316
Scope: 14 changed files. Prior security reviews covered the full diff through commit No critical or important security vulnerabilities found. New in
|
| Surface | Finding |
|---|---|
plugin.json (both plugins) |
Version bumps only — no new permissions, capabilities, or dependencies |
CHANGELOG.md (both plugins) |
Documentation only |
| GitHub Actions | No workflow files touched |
| Shell execution | The only shell calls in SKILL.md are bash "${CLAUDE_PLUGIN_ROOT}/..." using harness-provided env vars; --opinion and --no-stopping-condition are prose-interpreted behavioral controls, not shell-interpolated |
| External egress | No new programmatic fetch targets |
| Credential / secret handling | settings.local.json extraction is bounded by the prose constraint "prompt text only; never carry a command line, token, or other secret-bearing value"; audit-permission-grants/reference/criteria.md separately states the file is "never read or echoed wholesale (it may hold tokens)" |
| Supply chain | No new action pins or package dependencies |
| Path traversal | ${CLAUDE_PLUGIN_ROOT} and ${CLAUDE_PLUGIN_DATA} throughout — plugin-scoped harness vars |
SUGGESTION (carry-forward) — cross-plugin relative path in conflict-criteria.md.
Line 38: ../../../../claude-memory/skills/audit/reference/criteria.md. This is a markdown hyperlink for human readers, not a fetch target, so it is not exploitable. In an installed plugin cache the path would not resolve across the plugin root boundary — this violates the repo's own plugin-form-safe rule ("No ../ reach-outs"), but has no security consequence. Noted for future maintainers.
SUGGESTION (carry-forward) — unversioned raw.githubusercontent.com URL.
audit-permission-grants/reference/criteria.md line 9: pinned to main. Not a current vulnerability — the file carries the fix text inline and the SKILL.md states "a run never depends on fetching the convention." Risk materializes only if ever promoted to a live fetch; at that point, pin to a commit SHA.
Report-only contract maintained throughout. SKILL.md states no --fix. I15's managed-policy case carries "never manufacture a diff to satisfy the table." No automated write path exists on any surface inventoried by this PR. Output writes only to ${CLAUDE_PLUGIN_DATA}/audit-instructions/last-audit.md.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3714d36cfe
ℹ️ 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".
The known limit still said Phase A never reaches plugins/ and that agent-versus-memory pairs have no second side. The read-only inventory tier makes that false for every installed, enabled plugin, so two executable instructions disagreed about whether the same data is available. Narrowed to what remains true: a marketplace repository's plugins/ authoring tree is plugin source, not an installed plugin, and nothing there loads into the session being audited. The tier-transparency line reports that limit only. Also restores the section heading this file lost when the effective-liveness gate was inserted above it.
|
Claude finished @kyle-sexton's task in 5m 0s —— View job PR Review — feat(claude-config): add the cross-surface instruction-conflict checks and an OPINION tier
New commit (5d1f4fe) — clean, closes the last Codex P2The commit corrects the stale plugin-source limitation in One finding remains openBlanket
|
|
Claude finished @kyle-sexton's task in 2m 31s —— View job Security Review — PR #1316
Scope: 14 changed files — two No critical or important security vulnerabilities found. This PR is entirely prose and configuration. Specific checks:
Latest commit
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5d1f4fe105
ℹ️ 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".
Auto memory's enabled state was read from any single scope's false. It is resolved by precedence: CLAUDE_CODE_DISABLE_AUTO_MEMORY is authoritative wherever set (=1 off, =0 on even against autoMemoryEnabled: false), and with it unset settings precedence decides, defaulting to on. Reading a lower-scope false as decisive would drop a MEMORY.md a higher scope re-enabled. /claude-memory:stateless owns that resolver. The residency table also made every agent-definition-versus-MEMORY.md pair guaranteed, but the main conversation's auto memory is not loaded into subagents — only a fork inherits it. That pair now fails gate 1, while the two real ones stay: a fork, and a subagent's own memory directory against the definition it runs under.
|
Claude finished @kyle-sexton's task in 2m 8s —— View job PR Review — feat(claude-config): add the cross-surface instruction-conflict checks and an OPINION tier
New commit (5722cee) — closes both Codex P2s from the prior roundThe commit addresses the two P2s Codex raised on Two Codex P2 findings closed since the prior review pass
One finding remains openBlanket
|
|
Claude finished @kyle-sexton's task in 2m 14s —— View job Security Review — PR #1316
Scope: 14 changed files — two No critical or important security vulnerabilities found. New commit
|
| Surface | Finding |
|---|---|
plugin.json (both plugins) |
Version bumps only — no new permissions, capabilities, or dependencies |
CHANGELOG.md (both plugins) |
Documentation only |
| GitHub Actions | No workflow files touched |
| Shell execution | SKILL.md shell calls use bash "${CLAUDE_PLUGIN_ROOT}/..." with harness-provided env vars; instruction-scan.sh and conflict-scan.sh are referenced but not modified in this PR. The --opinion and --no-stopping-condition flags are prose-interpreted behavioral controls, not interpolated into shell strings |
| Credential / secret handling | "Extract the prompt text only; never carry a command line, token, or other secret-bearing value" constraint applies uniformly; settings.local.json is "parsed for its permissions.allow array only — never read or echoed wholesale (it may hold tokens)"; prompt hook text enters the comparison set as the act it gates rather than as raw prose — correct |
| Supply chain | No new action pins or package dependencies |
| Path traversal | All execution paths use ${CLAUDE_PLUGIN_ROOT} and ${CLAUDE_PLUGIN_DATA} — plugin-scoped harness vars |
| Managed-policy reads | Read-only for conflict comparison; criteria explicitly forbid any proposed edit to the managed-policy tier; no-change representation exempts those findings from the diff contract |
| Report output | Writes only to ${CLAUDE_PLUGIN_DATA}/audit-instructions/last-audit.md — local-only, no exfiltration path |
SUGGESTION (carry-forward from prior reviews) — ../../../../ relative path in conflict-criteria.md
Confidence: high · Not exploitable
plugins/claude-config/skills/audit-instructions/reference/conflict-criteria.md line 38:
[`plugins/claude-memory/skills/audit/reference/criteria.md`](../../../../claude-memory/skills/audit/reference/criteria.md)Four directory traversals toward a sibling plugin. In an installed plugin cache this path would not resolve across the plugin root boundary. The target file is a documentation reference for human readers, not a programmatic fetch target — there is no execution path following this link. The finding violates the repo's own plugin-form-safe rule ("No ../ reach-outs" in CLAUDE.md) but carries no exploitable consequence. Converting to prose or a public URL would close the design-rule gap.
SUGGESTION (carry-forward from prior reviews) — unversioned raw.githubusercontent.com URL
Confidence: high · Not a current vulnerability
plugins/claude-config/skills/audit-permission-grants/reference/criteria.md line 9:
https://raw.githubusercontent.com/melodic-software/claude-code-plugins/main/docs/conventions/permission-rule-hygiene/README.md
Pinned to main (mutable). Explicitly mitigated in the same file: "Each check's Recommend line below carries the fix in the form the report needs, so a run never depends on fetching the convention." Not a current vulnerability — risk materializes only if ever promoted to a live programmatic fetch, at which point the URL should be pinned to a commit SHA rather than main.
Report-only contract maintained. SKILL.md states no --fix flag. I15's managed-policy case carries "never manufacture a diff to satisfy the table." The no-change representation for managed-policy and upstream-owned findings explicitly exempts those from the diff contract. No automated write path exists on any inventoried surface.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5722cee390
ℹ️ 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".
| (the highest-precedence scope that sets `autoMemoryDirectory`, otherwise | ||
| `~/.claude/projects/<project>/memory/`). **Resolve the effective enabled state first, by |
There was a problem hiding this comment.
Honor CLAUDE_CONFIG_DIR for the default memory store
When CLAUDE_CONFIG_DIR is set and no scope supplies autoMemoryDirectory, this fallback scans ~/.claude/projects/... even though the entire config tree, including projects/, moves under CLAUDE_CONFIG_DIR (the sibling resolver documents this in plugins/claude-memory/skills/stateless/scripts/scope-report.sh:46-48). The conflict corpus consequently misses the live MEMORY.md and may inspect stale memory under the old root; derive the default from the already-resolved config root.
Useful? React with 👍 / 👎.
| removes them from every dispatch rather than deferring them. Name a destination the agent itself | ||
| reaches — a skill the agent's definition invokes or preloads, or text kept in the definition — and | ||
| never a `paths:`-scoped rule. |
There was a problem hiding this comment.
Exclude preloads from load-deferring destinations
When the agent lists the destination skill in its skills: preload, the skill's full body is injected into every dispatch (reference/conflict-criteria.md:90), so the sometimes-relevant content remains present during every unrelated use of the general-purpose agent. That contradicts the new requirement at lines 110-112 that an I3 destination must actually defer loading; permit only conditional runtime invocation here, or report that no safe deferral is available.
Useful? React with 👍 / 👎.
| Two pairs remain real and should not be swept away with it: a **fork** does inherit the parent, and a | ||
| subagent that enables its own `memory` can contradict the definition it runs under, but that is the | ||
| subagent's own memory directory, not the main conversation's. |
There was a problem hiding this comment.
Add agent-specific memory to the comparison corpus
After correctly excluding the main conversation's MEMORY.md, this retains conflicts with memory enabled by an agent's memory field, but Phase A inventories only the main project's effective auto-memory entrypoint (SKILL.md:131-148) and never enumerates each agent's separate memory directory. An agent-definition-versus-own-memory conflict therefore cannot reach B2 despite being declared real here; inventory the loaded portion of each enabled agent memory read-only, subject to the effective auto-memory gate.
Useful? React with 👍 / 👎.
| - **Upstream-owned instruction text that is nonetheless live** — skill bodies and agent definitions | ||
| from the cache of an **enabled** plugin, `type: "prompt"` handler text in an enabled plugin's | ||
| `hooks/hooks.json` (a plugin is a supported hook location and `prompt` a supported handler type, so | ||
| that text is as live as a settings-configured hook), **the active output style when a plugin |
There was a problem hiding this comment.
Apply hook disablement before inventorying plugin hooks
When the effective settings set disableAllHooks: true, an enabled plugin's prompt handler remains on disk but cannot run; plugin enablement alone therefore does not establish that its gate is live. Because the new liveness procedure resolves only the listed memory/session controls, B2 can report conflicts against a gate that is disabled for the session. Resolve effective hook enablement as well and omit disabled prompt handlers from the corpus.
Useful? React with 👍 / 👎.
…instructions and setup (#2003) ## Summary Discharges nine verifier-confirmed review findings against `claude-config`'s `audit-instructions` and `setup` skills, and bumps the plugin to `0.21.10` with a changelog entry. Seven of the nine are instruction-surface defects in `audit-instructions` — a skill that audits other people's instruction surfaces and was violating its own rules on three of them. One is a scanner false negative reproduced and fixed with tests. One is a prerequisite the docs understated by two skills. ## What changed, per finding | # | Complaint | Discharge | |---|---|---| | 1 | The skill forbids hardcoding `~/.claude`, then hardcodes it | `SKILL.md:45`, `:75`, `:197`, `:219-222` now resolve against the user root Phase A establishes | | 2 | I3 rejects `@path` imports as non-deferring, then names a `skills:` preload as a valid destination | `criteria.md:196-201` strikes the preload; only conditional runtime invocation qualifies | | 3 | A subagent's own `memory` is graded real but never inventoried | Inventory bullet at `SKILL.md:216-229`; co-residency row at `conflict-criteria.md:98` | | 4 | The liveness gate resolved a closed five-input list with no hook enablement | `SKILL.md:175-185` and `conflict-criteria.md:270-292` resolve `disableAllHooks` per scope plus `allowManagedHooksOnly` | | 5 | A nested project memory pair routed to a check that cannot discover the file | `SKILL.md:413-417` narrows the boundary to **root-level** project; `.claude/rules/**` deliberately unchanged | | 6 | `BOUNDARY_ERE` omits `and`, dropping a real conflict | `COORD_ERE` / `COORD_HEAD_ERE` at `conflict-scan.sh:131-143`, three new test cases | | 7 | The requirements list names only `jq`/`curl` | `README.md:163-177` and `setup/SKILL.md:28-33,46-52,106-108` name `awk`/`sort` across all three skills that use them | | 8 | I14's startup set omits `./.claude/CLAUDE.md` | `criteria.md:612-621` covers both supported root locations | | 9 | I14's supporting-document exemption ignores startup `@path` imports | `criteria.md:636-642` resolves imports first, to four hops | ### Finding 6, reproduced `conflict-scan.sh --count` on the finding's exact strings: | Case | `origin/main` | this branch | |---|---|---| | "Always use `Read` and never use `Bash`" vs "Never use `Read`" | 0 | **1** | | "Always use `Read` but never use `Bash`" vs "Never use `Read`" | 1 | 1 | A **bare** `and` boundary would also return 1 for the first row while creating a new false negative: "Never use `Bash` and `Grep`" is one directive over two objects, and cutting at the coordinator strips the `never` governing `Grep`. The boundary therefore requires a polarity token after `and`, and is consumed asymmetrically — a leading window resumes after the coordinator alone so that token still classifies its entity. Case 35 is the must-not-flag test and fails under a bare-`and` boundary. ### Citations re-verified against the live docs Every citation this batch introduced was diffed character-for-character against the raw markdown of `hooks`, `memory`, and `sub-agents` (fetched 2026-08-08). Three did not survive and were corrected: - **`disableAllHooks` has no documented "own settings level and below" cascade.** The docs say "Disable all hooks", with exactly one carve-out: set in user, project, or local settings it cannot reach managed hooks. The earlier wording invented a directional cascade. Rewritten. - **The `skills:` citation was a splice** of the frontmatter-table sentence and the body sentence, quotable as neither. Replaced with the real one: "The full content of each listed skill is injected into the subagent's context at startup." - **Imports recurse "with a maximum depth of four hops"** — the text pointed at a "hop limit" the page never names. Now states the figure and quotes the wording. Also corrected: the `AGENTS.md` import is *recommended* (a symlink is a co-equal alternative, and the import is mandated only on Windows), not prescribed; subagent memory paths take upstream's `<name-of-agent>` placeholder; and the auto-memory gate now names what the subagent actually loses — "the memory instructions or the memory tool access". ### Also fixed in passing `conflict-scan.test.sh:378` had unescaped backticks inside a double-quoted assertion message, so the suite ran `and` as a command (`and: command not found` on stderr) and printed the label with a hole in it. Exit status stayed 0, so no gate saw it. Now single-quoted, matching the file's existing idiom. ### Deliberately not changed - `${CLAUDE_CONFIG_DIR:-~/.claude}` — that form *is* the correct resolver, not a hardcode. - `~/.claude` inside quoted upstream text (`criteria.md:651`, `conflict-criteria.md:111`) — altering a quotation is a worse defect than the one it would resolve. - `.claude/rules/**` routing to `claude-memory`'s C6 — C6's rules discovery is recursive, so nested rules do not leak. Finding 5 is narrower than filed. ## Testing - `conflict-scan.test.sh` — 46/46, no stderr noise - All 7 `claude-config` plugin tests — PASS - `check-changelog-parity.sh` `--check` / `--check-bump origin/main` / `--check-order` — PASS - `check-changed-skills.sh origin/main` — 4 skills, 0 failed (`audit-instructions` 281/500 lines) - `check-shell-portability.sh` / `check-skill-portability.sh` — PASS - `shellcheck`, `markdownlint-cli2`, `typos` — clean - `validate-plugins.sh`, `check-contract-slice-prune.sh`, `check-contract-clause-coverage.py`, `check-silent-skips.sh`, `check-cross-plugin-source-drift.sh`, `check-skill-leaf-names.sh`, `check-orphaned-fixtures.sh` — PASS ## Related Discharges review findings filed on #1316, #1343, and #1349. No linked issue --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ckRollup running-check pitfall (#2513) ## Summary Lands the two PR-lifecycle facts #1436 recorded from driving #1393/#1316/#1318/#1322 to merge, in the document that was prescribing the expensive path: - **Stale-branch recovery now defaults to merge-forward.** `monitor.md`'s mergeable pre-check (§3.1 step 1) and stale-branch recovery rule (§3.2) both prescribed "force-push with lease" — but auto-mode permission classifiers commonly deny force-push, and the recorded consequence was a fresh branch + fresh PR + closing the old one per rebase (the #1315 → #1377 → #1393 churn, with every review thread re-opened on the successor). Merging the default branch *into* the PR branch resolves staleness and pushes **fast-forward** — no force-push — and under a squash-only default branch the merge commits collapse to one commit on merge, so linear-history requirements stay satisfied. Verified in the issue's own record: #1393 landed that way and #1318 was merge-forwarded five times without needing a new branch. Rebase stays available as the exception for projects requiring a linear PR branch where force-push is actually permitted. - **`statusCheckRollup` reports a running check as `conclusion: ""` (empty string), not `null`.** The complement-shaped filter (`conclusion != null and != "SUCCESS"`) therefore counts every in-progress check as a failure — the exact misreport in the issue (two "failing" checks that were simply still running). The multi-PR scan section (§3.0.6, the one place this skill reads `statusCheckRollup`) now documents the pitfall with value-positive jq selectors for "failed" and "still running". Version `0.53.11` → `0.53.14` (patch; `0.53.12`/`0.53.13` are claimed by in-flight PRs #2450/#2453/#2483/#2510 and #2469 — skipping past them per the #1746 collision pattern). ## Test plan - `npx markdownlint-cli2@0.23.2` on both edited markdown files — 0 issues. - Docs-only change to skill reference text; no scripts or hooks touched. The jq forms added are the ones from the issue, verified against `gh pr view --json statusCheckRollup` semantics. ## Related Fixes #1436 Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Kyle Sexton <kyle-sexton@users.noreply.github.com>
…ckRollup running-check pitfall (#2513) ## Summary Lands the two PR-lifecycle facts #1436 recorded from driving #1393/#1316/#1318/#1322 to merge, in the document that was prescribing the expensive path: - **Stale-branch recovery now defaults to merge-forward.** `monitor.md`'s mergeable pre-check (§3.1 step 1) and stale-branch recovery rule (§3.2) both prescribed "force-push with lease" — but auto-mode permission classifiers commonly deny force-push, and the recorded consequence was a fresh branch + fresh PR + closing the old one per rebase (the #1315 → #1377 → #1393 churn, with every review thread re-opened on the successor). Merging the default branch *into* the PR branch resolves staleness and pushes **fast-forward** — no force-push — and under a squash-only default branch the merge commits collapse to one commit on merge, so linear-history requirements stay satisfied. Verified in the issue's own record: #1393 landed that way and #1318 was merge-forwarded five times without needing a new branch. Rebase stays available as the exception for projects requiring a linear PR branch where force-push is actually permitted. - **`statusCheckRollup` reports a running check as `conclusion: ""` (empty string), not `null`.** The complement-shaped filter (`conclusion != null and != "SUCCESS"`) therefore counts every in-progress check as a failure — the exact misreport in the issue (two "failing" checks that were simply still running). The multi-PR scan section (§3.0.6, the one place this skill reads `statusCheckRollup`) now documents the pitfall with value-positive jq selectors for "failed" and "still running". Version `0.53.11` → `0.53.14` (patch; `0.53.12`/`0.53.13` are claimed by in-flight PRs #2450/#2453/#2483/#2510 and #2469 — skipping past them per the #1746 collision pattern). ## Test plan - `npx markdownlint-cli2@0.23.2` on both edited markdown files — 0 issues. - Docs-only change to skill reference text; no scripts or hooks touched. The jq forms added are the ones from the issue, verified against `gh pr view --json statusCheckRollup` semantics. ## Related Fixes #1436 Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Kyle Sexton <kyle-sexton@users.noreply.github.com>
The criteria payload for the
audit-passeffort: new checks in the two catalogs that already own their surfaces, rather than a new catalog.No linked issue.
What lands
claude-config:audit-instructionsgains I12 and I13, plus anOPINIONtier for rules that ship marked and default-off. I12 is the cross-surface instruction-conflict check — the one finding in this effort with no incumbent. It is scoped by routing rather than by assertion:claude-memory:audit's C6 already owns contradictions within the memory layer, so I12 takes cross-layer, non-memory, and managed-tier conflicts and does not duplicate it.claude-memory:audit's C3 (Content Placement) gains three gaps closed in one revision. They land as one edit rather than three checks, because the routing table answers one question and three checks would emit three findings for one misplaced section.Two corrections absorbed late, both worth calling out
CLAUDE.mdwithout expanding@pathimports is reading a different surface than the model sees — imported files are expanded into context at launch. Without this, every@docs/foo.mdimport is invisible to the check.AGENTS.mdis excluded by reachability, not by filename. Claude Code does not read a bareAGENTS.md, but the official docs steer repositories toward@AGENTS.mdorln -s AGENTS.md CLAUDE.md, and both make it live. A filename-based exclusion would have silently dropped the conflict class in precisely the repositories following official advice. Confirmed empirically: with the import in place,/contextenumeratesAGENTS.mdas its own loaded Memory Files row.The one empirical claim in the C3 revision is carried with explicit provenance rather than stated as documented behavior.
Verification
check-changelog-parity.sh --checkand--check-bump,check-skill-portability.sh,check-silent-skips.sh, andvalidate-plugin-contracts.mjspass on the rebased branch.skill-quality:checkonaudit-instructions: PASS, 0 errors, 0 warnings — 188/500 lines, description 666/1536 chars, all 6 base-ref trigger phrases preserved, markdownlint clean, and its script test passes.Merge-order note
This branch takes
claude-memoryto 0.5.0. #1315 carries a 0.4.1 for the same plugin that is not onmainyet. Whichever merges second needs the other's changelog entry inserted in order — the resolution is mechanical, but it is not a clean auto-merge.Review focus
The catalog text was written by one context and has not had an independent read. I12's surface list and the Type B allowlist are the two places where a fresh reviewer is most likely to find something: Type B conflicts (one absolute, one conditional, same act) ship only with a curated safety-critical allowlist, and that dependency is meant to be binding rather than advisory.
Related
claude-memorychangelogmcp-toolstool-search coverage gap, scoped out of this effort🤖 Generated with Claude Code