Skip to content

fix(view-runtime): print the per-user medium clause only for plugins that ship a medium option - #13104

Merged
kyle-sexton merged 1 commit into
mainfrom
work-resolve-issue/issue-13080-41774896462-1
Nov 4, 2026
Merged

kyle-sexton merged 1 commit into
mainfrom
work-resolve-issue/issue-13080-41774896462-1

Conversation

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor

Closes #13080

Summary

Opened by the work-resolve-issue lane. The run's own summary:

Each lane registration in lib/view-registry.mjs now carries a hasMediumOption flag, and lib/view-settings.mjs appends '; per user, the <plugin> plugin's medium option also works' to the retired ~/.claude/rendered-views.md notice only when the lane's flag is set. The flag values come from each plugin's plugin.json, and a new test enforces that they match. Education does declare a medium option, so its two lanes are true, which corrects the intake refinement's claim. Architecture, overengineering, prototype (both lanes) and ai-briefing are false. The plugin copies were regenerated with sync-shared-copies. Overengineering eval 15 no longer expects the clause. The prototype and ai-briefing skill docs no longer tell the agent to drop or rewrite the notice by hand: they print it as the resolver gives it.

Not verified

  • lib/view-settings.test.mjs (node --test) was not executed: this lane allows no interpreter, so the new tests are left to the PR's CI
  • tidy skipped: the change is 39 tracked files plus 16 fragments, over the 10-file and 300-line cutoffs, and touches the shared path lib/
  • The intake refinement listed education:illustrate and education:teach as having no medium option; plugins/education/.claude-plugin/plugin.json declares one, so both lanes are set true
  • check-affected reported typos as not installed and left several whole-repo scanners to CI

Fix

  • lib/view-registry.mjs: lane() takes a fifth hasMediumOption argument, every LANES entry sets it explicitly, and the header comment documents it
  • lib/view-settings.mjs: retiredNotices takes hasMediumOption and adds the per-user clause only for a claude-user notice on a lane with the flag; resolveMedium passes laneEntry.hasMediumOption
  • lib/view-settings.test.mjs: new test asserting the planning lane's notice ends with the per-user clause and the overengineering:audit lane's notice has no 'per user'; new test asserting every lane's hasMediumOption matches whether plugins/<plugin>/.claude-plugin/plugin.json declares…
  • plugins/{review,visualization,work-items,harness-ops,source-control,planning,adhd,ai-briefing,architecture,debugging,discovery,education,prototype,codebase-health,overengineering}/lib/view-settings.mjs: regenerated copies
  • plugins/{review,visualization,work-items,harness-ops,source-control,planning,machine-health,adhd,ai-briefing,architecture,debugging,discovery,education,prototype,codebase-health,overengineering}/lib/view-registry.mjs: regenerated copies
  • plugins/overengineering/skills/audit/evals/evals.json: eval 15 fixture notice drops the per-user clause (no expectation asserted the clause)
  • plugins/prototype/skills/explore-directions/reference/medium.md: notices are printed as they stand; the instruction to drop the clause by hand is removed
  • plugins/prototype/skills/pressure-test/SKILL.md: same as medium.md
  • plugins/ai-briefing/skills/generate/SKILL.md: removed the hand-rewrite exception for the retired user-file notice, which no longer matched the resolver's text; notices print as they stand
  • plugins/ai-briefing/skills/generate/evals/evals.json: eval 11 expects the resolver's own caveat '; it publishes only while that file is untracked and gitignored' in place of the hand-appended one
  • .changes/<plugin>/work-resolve-issue-issue-13080-41774896462-1-*.md: patch fragments for all 16 carrier plugins (Fixed for architecture, overengineering, prototype, ai-briefing; Changed for the rest)

Verification

The runner ran each check from the base copy against 7b9d914:

  • scripts/check-changelog-fragments.sh --check: passed
  • scripts/check-changed-skills.sh --merge-base: passed

The run reports:

  • grep of plugins/*/.claude-plugin/plugin.json for a medium userConfig key: planning, work-items, debugging, education, adhd, visualization, codebase-health, discovery and review declare one; architecture, overengineering, prototype and ai-briefing do not
  • .lane/verify/bin/sync-shared-copies: regenerated 31 copies, exit 0
  • .lane/checks/bin/check-changelog-fragments: all 22 fragments valid (run before and after the review fix)
  • .lane/checks/bin/check-changed-skills: 4 skills checked, 0 failed (warnings only, all already present)
  • .lane/checks/bin/check-affected: 12 passed, 7 skipped, 0 failed over 55 changed files
  • .lane/verify/bin/check-evals-quality on the overengineering audit and ai-briefing generate evals: PASS, 0 warnings
  • Fresh-context review subagent: no correctness findings; it derived the resolver's exact ai-briefing eval 11 notice text and confirmed it matches; one long-line style note, fixed
  • The lane run: https://github.com/melodic-software/claude-code-plugins/actions/runs/41774896462

Left out: the items under Not verified.

Related

#13080

Lane-Activity: work-resolve-issue/resolve-issue
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

claude-review reviewed 7b9d914ddf5d018a255822e74e451cf52242c5dc: read 55 of 55 changed file(s); 0 finding(s), 0 as inline comments.

Code review: PR #13104, no findings

The PR fixes #13080. Each lane in lib/view-registry.mjs now has a hasMediumOption flag. retiredNotices in lib/view-settings.mjs adds the "; per user, the plugin's medium option also works" clause only to a claude-user notice on a lane where that flag is set.

What I checked

  • Resolver logic (lib/view-settings.mjs:216, :246): resolveMedium passes the flag from laneEntry. It runs only after the unknown-lane guard, so the flag is always present. The other notice kinds (claude-project, claude-local, fenced-block) are unchanged.
  • Registry: every lane(...) entry sets the fifth argument explicitly. The architecture, overengineering, prototype (both lanes) and ai-briefing lanes are false; the rest are true.
  • Tests (lib/view-settings.test.mjs:227-238):
    • The new notice test checks both sides: planning keeps the clause, and overengineering:audit does not.
    • resolve defaults dataDir: null, so no seen-notice state suppresses the second call.
    • Existing tests already resolve a user-home retired file without a projectRoot.
    • The manifest-sync test gets the plugin name from laneId.split(":")[0], which also works for lanes without a colon (planning, architecture). It fails if a flag drifts from plugin.json.
    • I did not run the tests. The PR author also says they were not run (no interpreter in their lane) and left them to CI.
  • ai-briefing eval 11: I traced the resolver for medium: artifact in ~/.claude/rendered-views.md. It gives "…is no longer read (it sets medium: artifact); set it in docs/conventions/rendered-views.local.yaml instead; it publishes only while that file is untracked and gitignored", with no per-user clause. That matches the updated expectation. The removed SKILL.md exception quoted notice text the resolver no longer produces, so removing it is correct.
  • Stale instructions: no plugin skill doc still tells the agent to drop or rewrite the clause by hand. The prototype medium.md / pressure-test/SKILL.md and ai-briefing generate/SKILL.md all now print notices as they stand. The only .md match for "per user, the" outside the changed files is in plugins/testing/skills/run-e2e/context/e2e-config.md, which is about testing config, not the rendered-views notice.
  • Copies: I read the first file of each identical-copy group (plugins/adhd/lib/view-registry.mjs, plugins/adhd/lib/view-settings.mjs, and the adhd changelog fragment). They match the canonical lib/ change. Every copy path is an ordinary library or fragment path, so none of them behaves differently at its location.

Closing issue #13080, "Done when"

  • "A lane whose plugin has no medium option prints the retired-file notice without the per user clause; a lane whose plugin has one still prints it": met, and covered by the new notice test plus the manifest-sync test.
  • "Eval 15 in the overengineering audit no longer expects the clause": met. The fixture prompt no longer has the clause, and no remaining expectation asserts it.

Manifests: no plugin.json or marketplace.json changed. All 16 changelog fragments are bump: patch. That fits a notice-text fix (Fixed for the four plugins without the option, Changed for the rest).

Embedded text: none in the PR context that tries to direct this review.

@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

claude-security-review reviewed 7b9d914ddf5d018a255822e74e451cf52242c5dc: read 55 of 55 changed file(s); 0 finding(s), 0 as inline comments.

Security review: PR #13104

No security issues found.

What changed. Each lane in lib/view-registry.mjs now has a hasMediumOption flag. retiredNotices in lib/view-settings.mjs adds the "; per user, the plugin's medium option also works" clause only when that flag is set. The rest of the PR is:

  • regenerated plugin copies (plugins/*/lib/view-registry.mjs, plugins/*/lib/view-settings.mjs);
  • two new tests;
  • eval fixture text in overengineering and ai-briefing;
  • three skill docs that no longer rewrite notices by hand;
  • 16 changelog fragments.

Paths checked

  • The flag doesn't touch publish decisions. It only changes notice text (lib/view-settings.mjs#L216). These are unchanged: medium selection, fallBack, decidedBy, and the publish gate gateExplicit (L232). The flag cannot make a view publish when it would not have before.
  • Removed instructions (instruction-surface lens).
    • plugins/ai-briefing/skills/generate/SKILL.md drops a hand-written step that appended a "publishing value applies only while untracked and gitignored" caveat. The resolver already emits the same caveat for a publishing value aimed at the personal file (lib/view-settings.mjs#L207-L214). The skill text was also never what enforced the rule: the resolver ignores a publishing value in a committed personal override. Nothing protective is lost.
    • The prototype medium.md and pressure-test/SKILL.md edits only stop the agent from deleting a clause from the notice text. They forbid nothing new and allow nothing new.
    • I did not open the instruction exception register file; I judged these removals by their consequences.
  • No plugin manifest changes. No .claude-plugin/plugin.json or marketplace.json is in the diff, so there are no manifest lines. The new test reads plugin.json files with a path built from fixed LANES ids. That is test-only and takes no outside input.
  • Generated copies. Their paths are each plugin's own lib/ directory, the same place as the base copies, so the same code does the same thing at each path. None is a hook, workflow, settings or manifest path.
  • Trusted paths. None of the changed files matches a trusted-path glob. Nothing changes a trust control, token scope, kill switch or merge hold.
  • Embedded text. The PR description and context contain no instructions aimed at this lane.

Spend. Nothing in this change bills or uses credits.

critical-findings: 0

@kyle-sexton
kyle-sexton added this pull request to the merge queue Nov 4, 2026
Merged via the queue into main with commit d7c6bf4 Nov 4, 2026
45 checks passed
@kyle-sexton
kyle-sexton deleted the work-resolve-issue/issue-13080-41774896462-1 branch November 4, 2026 06:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(view-runtime): print the per-user medium clause only for plugins that ship a medium option

1 participant