Skip to content

Concise skills rollout: coupling (1 skills, 1 model-invoked) #6602

Closed

Description

@kyle-sexton

Part of #6476. Rewrite coupling's skills to the skill criteria in one draft PR, following the per-plugin runbook (/playbooks:skill-authoring, reference/rewrite-a-plugin.md). The runbook and the rewrite protocol it cites decide what ships; this issue holds only what is specific to the plugin.

Path: description-only, measured by trigger probes (owner decision on #6476, 2026-10-18: the 1-skill tail takes the description-only path). The body is not rewritten.

The plugin today

As of origin/main on 2026-10-24:

  • Skills: reduce (model-invoked).
  • Outcome eval case directories under the plugin: 0. Probe files under probes/: 0.

Done when

  • git diff origin/main -- plugins/coupling/skills changes no line outside the description key of plugins/coupling/skills/reduce/SKILL.md.
  • plugins/coupling/probes/reduce.json exists in the PR.
  • The PR body shows /skill-quality:check measure-invocation trigger scores for the before and the after description on the same probes.
  • The after description scores at least the before score, or the PR ships the before description and says so.
  • /skill-quality:check plugins/coupling on the PR head reports no FAIL that the run on main does not.
  • The plugin's version or changelog entry is in the PR, per the plugin's release mode.

Eval spend and review

  • Eval passes within prepaid API credit are pre-approved (owner decision Q46, 2026-10-24), at the --max-cost-usd 5 per-pass ceiling set on #6476 on 2026-10-18.
  • No person gates the PR: the owner's 2026-10-24 decision (C12) leaves only an intent mismatch during the build or a security issue at review as stops.

Generated by Claude Code

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 7, 2026
  2. github-actions commented on Oct 7, 2026

    @github-actions
    Contributor

    Proposed work class: work-class: scoped
    Basis: automated intake triage; the lanes App applied this class.

    Size: Small
    Complexity: Low
    Uncertainty: Known
    Flags: none
    Blocked by: none

    Understood: this is the coupling plugin's part of the #6476 rollout. It takes the description-only path. The only change is the description key of reduce/SKILL.md. A new probes/reduce.json measures the before and after descriptions. The PR also needs a version or changelog entry.

    The body is complete and the earlier hold was released by the owner's 2026-10-24 decision. Nothing is missing. Eval spend is prepaid and pre-approved. I found no duplicates.

    The issue carried both priority: low and priority: medium. I'm keeping one: medium.

    Automated triage, applied by the lanes App.

  3. removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 12, 2026
  4. added theissue type on Oct 12, 2026
  5. added
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    on Oct 19, 2026
  6. kyle-sexton commented on Oct 19, 2026

    @kyle-sexton
    MemberAuthor

    This was generated by AI during triage.

    Held for a person: The #6476 owner decision (2026-10-18) moves this 1-skill plugin to a description-only path measured by trigger probes, but this body still asks for a full rewrite and a person's eval-spend approval; the body and spend need the owner's update first.

  7. removed
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    on Oct 24, 2026
  8. kyle-sexton commented on Oct 24, 2026

    @kyle-sexton
    MemberAuthor

    Released by the owner's HITL session (2026-10-24, C12): it waited only on a removed gate. Intake triage re-runs on it to set its fields, then admission takes it.

  9. github-actions commented on Oct 25, 2026

    @github-actions
    Contributor

    The triage sweep dispatched intake triage for this issue (attempt 1 of 2).

  10. 13 remaining items

  11. kyle-sexton commented on Oct 27, 2026

    @kyle-sexton
    MemberAuthor

    This was generated by AI.

    Parked for capacity, not for the owner. This rollout's remaining work is the measured eval passes of the batch-1 protocol, which the issue lane cannot run: it cannot start claude or claude plugin eval (see the lane's escalation on #6585, https://github.com/melodic-software/claude-code-plugins/actions/runs/40186335064). It waits on the plugin eval dispatch work in #9704, now a blocked-by edge, so admission holds it until #9704 closes.

    Under the owner's 2026-10-26 stop rule, a person is needed only for a change in intent or vision, an implementation finding that changes the intent or primary design, or a high or critical security issue; host, attended and eval runs are agent work. So needs-human comes off, and the issue moves to host-run with status: confirmed, which keeps the issue lane from taking it when #9704 closes: #9704 adds an eval dispatch workflow, not eval capability for the issue lane.

  12. added
    host-runNeeds an unattended run on a host; the host runner takes it, not a person or the issue lane.
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    and removed
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    on Oct 27, 2026
  13. kyle-sexton commented on Oct 29, 2026

    @kyle-sexton
    MemberAuthor

    Re-triage. Not an owner stop. #10010 added plugins/coupling/probes/reduce.json. Its blocker #9704 is closed. Under the 2026-10-18 owner decision, this one-skill plugin takes the description-only path. The rest is a pair of trigger-score runs that only a Claude Code session can make, so the issue keeps host-run and the host runner takes it.

    Acceptance criteria:

    • git diff origin/main -- plugins/coupling/skills changes no line outside the description key of plugins/coupling/skills/reduce/SKILL.md.
    • The PR body shows /skill-quality:check measure-invocation trigger scores for the before and the after description, both on plugins/coupling/probes/reduce.json.
    • The after description scores at least the before score. If it does not, the PR ships the before description and says so.
    • /skill-quality:check plugins/coupling on the PR head reports no FAIL that the run on main does not report.
    • The coupling version or changelog entry is in the PR, per the plugin's release mode.
  14. added
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    and removed
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    on Oct 29, 2026
  15. kyle-sexton commented on Oct 31, 2026

    @kyle-sexton
    MemberAuthor

    Host run. Description-only trigger screen for coupling:reduce: before and after copies launched together, frozen probes.

    What ran

    • Claude Code 2.1.316, base a781adf89a, models claude-opus-5-5 and claude-sonnet-5-5, --ablation none, -j 2, cases from measure-invocation.sh emit-plugin-eval, 20 probes (10 positive, 10 negative), digest a7a55f0d4b33.
    • Description length: 982 to 880 characters (10.4%). Probes were the frozen file on main. The rewriter was barred from reading probes and evals, and kept every quoted trigger phrase.
    • Rule written before any after-version result: --runs 1 screen, then --runs 3, where after must score at least before on every model (the done-when), or the before description ships.
    • Meaning diff: two labelers, union of losses. PASS from both.
    • Command in short form: claude plugin eval <copy> --eval-dir trigger --model <model> --ablation none --runs N -j 2 --keep-temp --max-cost-usd 5, each in a capped scope.
    • Result files: /home/kyle/worktrees/host-run-tail-eval/out/<label>-before.json and -after.json, labels s1-coupling-opus, s1-coupling-sonnet, s3-coupling-sonnet, s3-coupling-opus-pos. Rule: PREREG.md beside them. Frozen probes: /home/kyle/worktrees/host-run-tail-eval/probes/coupling/reduce.json.

    Done-when

    • Description-only diff: not covered, no PR. The run copies differed only in the description.
    • Probe file in the PR: met on main (test(coupling): add frozen trigger probe set for reduce #10010).
    • Before and after scores in the PR body: not covered, no PR. They are in this record.
    • After at least before, or the PR ships the before description: not met: sonnet held, opus unreadable, opus negatives not run.
    • /skill-quality:check, no new FAIL: met on the local change: PASS, 0 errors, 2 warnings, same as main.
    • Changelog entry: not met, no PR.

    Scores (hits on both polarities, over probes x runs)

    Pass Model Before After
    screen 1 run opus 20/20, denial shape not recorded 20/20, denial shape not recorded
    screen 1 run sonnet 16/20 17/20
    gate 3 runs sonnet 50/60 51/60
    gate 3 runs, positives opus 30/30, unreadable 30/30, unreadable

    Result

    Not shipped from this run; the before description stands on main. Sonnet held (50/60 to 51/60). The opus positive pass scored 30/30 in both versions, but 6 runs in each hit a Grep or Glob denial at the sandbox root, a granted tool. The written rule fails such a pass, run-validity fails it too because pos-train-05 has no denial-free run, and this run did not rewrite that rule after reading the score. Remaining: decide in advance how a trigger pass treats a denial that lands after the skill has fired, rerun the opus gate under that rule, then open the PR.

    Caveats

    • run-validity.py has no trigger mode: a missed positive prints INVALID on skill fired, and an ungranted-tool No such tool available error prints a denial. Both were read per an addendum written before any --runs 3 pass, the same for both versions. That addendum fails a pass on a denial of a granted tool, and every other row had to pass.
    • The eval loads one plugin, so these numbers show no rival skills from other plugins. A score at the ceiling cannot show an improvement.
    • No separate held-out set ran: the rewriter never saw these probes and cut no quoted phrase.
    • /skill-quality:check on the plugin matches main with the description applied: PASS, 0 errors, 2 warnings.
    • An unpushed local change sits in /home/kyle/worktrees/host-run-6602: description, changelog fragment, no commit.
    • The opus screen predates denial capture, so its 1 and 2 denials are unclassified. It decided only escalation.
    • This run moved the launch cutoff from 10:50Z to 10:55Z with no addendum; the opus positive pair started at about 10:50Z. The opus negative pair was stopped before finishing and reports no number.

    Target labels: add none; remove none.

  16. kyle-sexton commented on Nov 2, 2026

    @kyle-sexton
    MemberAuthor

    Claimed by Lane 5 (melo-lap-001), handed over by Lane 3.

  17. kyle-sexton commented on Nov 2, 2026

    @kyle-sexton
    MemberAuthor

    Host run (Lane 5): description-only trigger measurement for coupling:reduce. Result: the before description stays, and no PR is opened.

    What ran

    • Claude Code 2.1.316, base origin/main 31fb15a347. Models claude-opus-5-5 and claude-sonnet-5-5.
    • Eval flags: --ablation none --runs 3 -j 2 --disallow-tools Read Glob Grep Agent --keep-temp --max-cost-usd 5. These are the emitted README's run line.
    • Before and after copies of each group launched together. run-validity.py (origin/main) judged all 20 passes VALID. No pass had a probe tools or denial warning, so the Grep/Glob sandbox-root denial that left the last opus run unreadable did not recur.
    • New blind rewrite: a fresh agent, barred from probes, evals and GitHub.
      • It kept all 13 quoted trigger phrases and all four Skip routes. The description goes from 982 to 918 characters.
      • Cuts: "typed against a coupling model" and "general" before "structural tidyings". Reword: "so repeated runs continue where the last stopped" became "so the next run resumes".
      • Meaning diff: two docs-hygiene:compare-labeler agents found 0 semantic loss and 0 ambiguity.
    • Probes:
      • Frozen: plugins/coupling/probes/reduce.json (20).
      • Held-out: 18 more (9 positive, 9 negative), written blind from a neutral purpose statement and not committed. This set is now spent.
    • Rule, written before any run: after hits must be at least before hits on the frozen set (this issue's done-when), and on every model. The held-out sets must be non-inferior at 5 points. No probe may go from 3/3 to 0/3.
    • Negative control (opus): a copy with the description reduced to "Helper for repository maintenance tasks." and the body unchanged. It tests whether this suite can detect a description loss at all.

    Scores (hits over probes x 3 runs)

    Set Opus before Opus after Sonnet before Sonnet after Opus degraded control
    frozen positives 30/30 30/30 28/30 26/30 24/30
    frozen negatives held 30/30 30/30 30/30 30/30 30/30
    held-out positives 27/27 27/27 23/27 22/27 18/27
    held-out negatives held 27/27 27/27 27/27 27/27 27/27

    Decision

    Skill Part Decision Basis
    reduce description before stays Opus held on every set. Sonnet frozen fell from 58/60 to 56/60, which fails the done-when rule: pos-train-03 went from 3/3 to 2/3 and pos-val-03 from 1/3 to 0/3. noise-report.py --margin 0.05 agrees: Sonnet frozen positives are not shown non-inferior (paired change -0.07, 95% interval -0.15 to +0.02), and neither are held-out positives (-0.04, -0.11 to +0.04). The control shows the suite can detect a loss: degraded opus positives were 42/57 against 57/57, 5 probes lost.
    reduce body unchanged, unmeasured The description-only path has no outcome cases.

    Headroom

    • Every opus probe was already 3/3 before, so on opus this suite can show a loss but not a gain.
    • Sonnet probes below the ceiling, with their before scores: pos-val-03 1/3, pos-ho-05 2/3, pos-ho-06 2/3, pos-ho-09 1/3. Every other probe was 3/3 on both models.
    • At 3 runs, a single missed run counts as a one-third case drop.

    Done-when

    • Description-only diff: not covered. No change ships, so there is no PR.
    • Probe file: met on main (test(coupling): add frozen trigger probe set for reduce #10010).
    • Before and after scores on probes/reduce.json: recorded in this comment. With no PR, there is no PR body to put them in.
    • After at least before, or the before description stands: not met for the after version on Sonnet. The before description stands on main.
    • /skill-quality:check: main is PASS, with 0 errors and 3 warnings. Nothing changes.
    • Changelog entry: not covered, since nothing changes.

    Spend: 20 result files, about 37 USD (list-price estimate, sum of costUsd). The kept sandboxes are deleted.

    What remains: a further description change needs a new rewrite round with a fresh held-out set. That round must beat a before version re-measured alongside it on each model.

    Target labels: add none; remove none.

  18. kyle-sexton commented on Nov 2, 2026

    @kyle-sexton
    MemberAuthor

    Restore round (Lane 5): the before description stays. No PR.

    This round follows the runbook's restore step (plugins/playbooks/skills/skill-authoring/reference/rewrite-a-plugin.md, lines 54-55) for the two Sonnet case drops in the previous run: pos-train-03 and pos-val-03. The rule was preregistered before the paid run.

    What changed and why

    Both dropped probes ask for the value-change mode: a timeout changed from 30s to 45s, and a product renamed. No cut text touches the value-change clause itself. The reword that sits right before that clause was the most likely carrier, so I restored it: "so the next run resumes" became "so repeated runs continue where the last stopped" again. The other two cuts stayed cut ("typed against a coupling model", "general"). The new after2 description is 943 characters, against 982 before.

    Run

    • Sonnet only, --runs 3, same flags as before.
    • After2 ran against a fresh before, launched together, on the frozen positives and the held-out positives.
    • After2 also ran alone on both negative sets.
    • All 6 passes were VALID under run-validity.py.
    Set Fresh before After2
    frozen positives 28/30 26/30 (pos-train-03 3/3 to 2/3, pos-val-03 1/3 to 0/3)
    held-out positives 24/27 22/27 (pos-ho-05 3/3 to 1/3, pos-ho-06 3/3 to 2/3, pos-ho-09 0/3 to 1/3)
    frozen negatives held not run 30/30
    held-out negatives held not run 27/27

    Decision

    Skill Part Decision Basis
    reduce description before stays The restore did not close the gap. The same two frozen probes dropped again, and after2 is below the fresh before on both positive sets. The runbook says that when no restore closes the gap, the before text ships.
    reduce body unchanged, unmeasured The description-only path has no outcome cases.

    The restored phrase is ruled out as the cause. On Sonnet, both rounds lose the same two value-change probes, which points to the shorter description as a whole rather than to one cut. That is an inference; I did not test the other two cuts one at a time.

    Done-when

    Unchanged from the previous comment.

    • The after version did not reach the before score on Sonnet, so the before description stands on main.
    • Nothing ships, so there is no PR, no diff and no changelog entry.

    Spend: 6 result files, 7.46 USD (list-price estimate). That makes 44.22 USD across 26 result files for this issue's two rounds. The kept sandboxes are deleted.

    Target labels: add none; remove none.

  19. kyle-sexton commented on Nov 2, 2026

    @kyle-sexton
    MemberAuthor

    Closing as completed: the rollout's per-skill decision is made and measured. Nothing changes in the plugin.

    Skill Part Decision
    coupling:reduce description before stays. The blind rewrite lost two Sonnet probes on frozen positives (28 → 26 of 30), and restoring the reworded phrase did not close the gap against a fresh before (r1, same two probes). Per rewrite-a-plugin.md step 5, "When no restore closes the gap, the before text ships." The opus negative control (42/57 vs 57/57) shows the suite detects a loss, so this no-ship rests on measured evidence.
    coupling:reduce body unchanged, unmeasured (description-only path, no outcome cases)

    The probe file is already on main (#10010). All 26 passes are VALID; the tables are in the round 1 and restore comments. A future description change would need a new blind round that beats a before version re-measured alongside it on each model.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    host-runNeeds an unattended run on a host; the host runner takes it, not a person or the issue lane.priority: mediumReal value, no hard deadline; normal backlog flow.status: readyTriaged, unblocked, and fully specified; eligible to pick up.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.

    Type

    Fields

    No fields configured for Task.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions