/affinage¶
Skill metadata
- License: MIT
- Source:
skills/affinage/SKILL.md
When to invoke: Triage a PR's review comments and failing CI (plus merge conflicts) through the /age lens, deciding which claims are worth acting on. Use when the user says "respond to PR comments", "handle review feedback", "affinage the PR", "/affinage gh and CI failures via affinage.pyz pr-status, grades each through the ten age dimensions, and writes a report at .cheese/affinage/pr-<n>.md. Resolves merge conflicts via /melt and routes build/CI failures to fixes through /cure. When invoked standalone (no upstream handoff_context) it also runs /age over the PR diff and folds fresh findings in; when chained, it skips that pass. By default it auto-applies the recommended set via /cure and posts the drafted replies, gating only on sprawling/structural fixes or conflicts; --safe re-gates. Supports --auto --stake <floor>. Before /cure; parallel to /age.
Use this skill when the user wants to act on external claims about a PR โ review comments from humans or bots, plus failing CI checks and merge conflicts โ and wants those claims graded through the same lens /age uses for fresh review, then handed to /cure for application.
/affinage always refines the claims that already exist on the PR (comments, CI failures, conflicts). Whether it also generates fresh /age findings depends on how it was reached:
- Standalone โ the user typed
/affinage <pr>directly, with no upstreamhandoff_context. The PR diff has not been reviewed in this session, so/affinageruns/ageover it and folds the findings into the same report (unless--no-age). - Chained โ reached from
/cookor/curewith ahandoff_context./agealready ran in that chain, so/affinageskips the fresh pass to avoid double-grading and only refines existing claims.
See ## Fresh-window review for the detection rule and ## Merge-conflict resolution for the conflict path.
The metaphor: an affineur evaluates each wheel of cheese by sight / smell / sound and decides its fate. Here the wheels are review comments, CI failures, and merge conflicts.
Inputs¶
/affinage [<pr-ref>] [--auto --stake <floor>] [--safe] [--open-pr] [--hard] [--full] [--include-outdated]
<pr-ref> accepts a PR number, a full GitHub PR URL, or nothing (auto-detect via gh pr view --json number on the current branch).
Flags:
--auto --stake <floor>โ autonomous mode.<floor>isblocker,high,medium+, orall(same semantics as/cure). Skips the selection gate, dispatches/cure --auto --stake <floor>, posts all replies without prompting.--safeโ re-introduce the gates the autonomous default skips: the cure-selection gate, the reply-only gate, and the merge-conflict confirmation. Use it when you want to choose before anything is fixed, replied to, or resolved.--open-prโ propagate to/cureso a clean cure may open a new PR when none exists (otherwise/cureonly pushes an already-open one). For an affinage run the PR almost always already exists, so this flag rarely matters here.--hardโ propagated metacognitive-gate flag./affinagedoes not fire the gate; passes--hardforward to/cureat handoff.--fullโ un-collapses## Lowwhen โฅ10 low-severity findings exist (mirrors/age --full).--include-outdatedโ include outdated review threads. Default skips them.--no-ageโ skip the standalone fresh/agepass. No effect when chained (the pass is already skipped). Use when you only want to triage existing comments, CI failures, and conflicts.
Flow¶
- Resolve PR. From
<pr-ref>orgh pr view --json numberon the current branch. Resolve<owner>/<repo>from the git remote. - Fetch PR status. Call
python3 ${CLAUDE_SKILL_DIR}/scripts/affinage.pyz pr-status <pr>. The script returns JSON with build status, per-check failure summaries (last ~10 lines of failed logs + parsed failed-test names), and merge state. Map the exit code: - Exit 0 โ proceed with grading.
- Exit 3 (
logs-expired) โ the build is failing but every failing check's log was unfetchable (typically expired GitHub Actions logs past the retention window), so there is nothing to ground a CI finding on. Writestatus: halt: pr-status-logs-expiredand stop with the hint: "CI is failing but the logs have expired โ rerun the failed jobs (gh run rerun <run-id> --failed, where<run-id>is the/actions/runs/<id>/segment of the failing check'surl, or read it fromgh pr checks) and re-invoke/affinage." Affineurs often run a few days after a PR opens, so this is routine, not an edge case. - Any other non-zero (1 PR/gh API error, 2 missing gh binary) โ write
status: halt: pr-status-unavailableand stop. - Merge conflicts. If
merge.mergeableisCONFLICTINGormerge.stateisDIRTY, the PR has unresolved conflicts. Resolve them before grading โ see## Merge-conflict resolution. - Fresh-window review. If this is a standalone run and
--no-agewas not passed, run/ageover the PR diff before grading and treat each finding as an additional input. See## Fresh-window review. - Fetch comments.
- Inline threads:
gh api repos/<owner>/<repo>/pulls/<pr>/comments. This REST endpoint returns individual review comments without thread-level resolution state, so the skill cannot filter onisResolvedfrom this surface; it skips comments whosepositionisnull(the diff has moved past the anchored line) unless--include-outdated. For true unresolved-only filtering, switch to the GraphQLpullRequest.reviewThreads { isResolved }endpoint โ documented as a future enhancement. - Review bodies:
gh api repos/<owner>/<repo>/pulls/<pr>/reviews. Filter to non-empty bodies. Dedupe against inline comments viapull_request_review_id. - Skip already-replied threads. A thread whose most recent comment is from the resolved GitHub handle (env
RESPOND_GH_HANDLEโgh api user --jq .loginโgit config user.name) has already been responded to; skip it. The same resolved handle is rendered in the reply footer asagent on behalf of <handle>. This keeps re-runs idempotent and makesRESPOND_GH_HANDLEthe explicit footer knob. - Grade through the age lens. For each input (comment, CI/build failure, OR fresh
/agefinding): - Classify dimension from the code + claim (or check type + failure summary, for CI items). See
skills/age/references/dimensions.mdfor the dimension rubric. - Build failures count, not just test failures. A failing check is a finding whether the failure is a compile error, a lint/type-check failure, or a failing test โ grade the
build.status: failingchecks fromaffinage.pyz pr-statusand route them to/cureexactly like test failures. Tag CI-sourced items[from-check:<job>]. - Fresh
/agefindings (standalone runs) arrive already dimension-classified and severity-scored; fold them into the buckets below tagged[from-age:<dimension>]. Dedupe against comment-sourced items echoing the same defect โ keep the comment-sourced one (it carries a reviewer to reply to). - Compute severity from base + location + compounding modifiers (same rubric as
/age). - Ignore reviewer-asserted urgency for severity computation. Surface
CHANGES_REQUESTEDas metadata (reviewer-asserted:line) but do not let it modify computed severity. - Bucket into:
- Standard severity sections (
## Blocker / ## High / ## Medium / ## Low) when the claim is grounded in the diff and its fix is contained (fix-cost-now: containedโ roughly a few lines or a localized refactor). Every such item still maps to a dimension and carries a[<dimension>:<severity>]tag โ a style or quality nit maps todeslop(e.g.[deslop:low]). The new rule is to route these grounded, contained-fix nits to/cure(usually asLow) instead of## Reviewer-rejected, keeping the[from-comment:<id>]tag so/cure's reply still reaches the reviewer; a valid cheap nit is cheaper to fix than to argue, so do not push back on it. ## Needs-investigationwhen the claim is plausible but requires evidence outside the diff (e.g., downstream caller in another repo).## Reviewer-rejectedonly when the claim is wrong or ungrounded (the code is already correct, the reviewer misread it, or there is no real improvement) OR is valid but a lot of follow-up work (fix-cost-now: moderate/sprawlingorfix-cost-later: structuralโ a refactor or scope expansion beyond this PR). Reject the wrong ones; defer the expensive ones. Perskills/age/references/voice.md, a justified push-back costs more than a small valid fix.
- Standard severity sections (
- Write report to
.cheese/affinage/pr-<n>.mdwith the four-line handoff slug at the top, then the age-format body plus the two extra sections. See## Outputbelow. - Act or ask. By default affinage acts โ auto-applies the recommended set and posts the drafted replies โ and asks only on a genuine reason (a sprawling/structural fix in the recommended set, conflicting findings) or under
--safe. Branch on what graded out (full gate shapes in## Handoff): - At least one finding in a severity section (
Blocker/High/Medium/Low). Compute the recommended composite (all-medium, cheap). With no reason to ask and no--safe: announce the selection in one line, first run step 9 to post any drafted push-backs / investigating notes (they don't depend on cure's outcome, so they must reach GitHub even if/curelater halts), then dispatch/cure <slug>with lockedhandoff_context:and post the cure-dependent replies (step 10) when/curereturns. On a reason to ask or--safe: render the cure-selection table inline using/cure's verbs (skills/cure/references/selection.md), pre-select the recommended composite (flagging heavy rows), ask viashared/handoff-gate.md, then proceed as above for the chosen selection; onnone/Stop, run step 9 for the drafted replies and exit with the report path. If the recommended set is empty (only heavy/expensive items graded into severity sections), treat it as the reply-only branch below. - No severity-section findings, but
Reviewer-rejectedorNeeds-investigationhas items. Skip/curedispatch entirely โ there is nothing to apply. By default run step 9 to post all drafted replies (push-backs + investigating notes). Under--safe, render a small gate first that lets the user pickpost all,post pushbacks only,skip posting, or per-finding choices. Exit withstatus: ok / next: done. This mirrors the documented auto-mode "no findings meet the floor" branch (see### Auto mode). - Nothing graded into any section. Exit cleanly with the report path; there is nothing to post or cure.
- Post non-cure replies (runs whenever grading produced these items, with or without
/cure). Post viapython3 ${CLAUDE_SKILL_DIR}/scripts/affinage.pyz post-reply: - Reviewer-rejected items โ post the pre-drafted push-back text from the affinage report.
- Needs-investigation items โ post
"Human investigating โ will follow up." - CI-sourced findings (
from-check:<job>tag) and fresh-review findings (from-age:<dimension>tag) โ no reply (no reviewer to notify).
Decoupling this from /cure is deliberate: drafted push-backs and investigating notes must reach GitHub even when no severity-section finding exists and /cure never runs โ otherwise the drafted reply is write-only, useful to the human reading the report but invisible to the reviewer waiting on GitHub.
10. Post-cure reply posting (only when /cure ran). When /cure returns, read .cheese/cure/pr-<n>.md's ### Applied / ### Deferred sections and post per-finding replies via python3 ${CLAUDE_SKILL_DIR}/scripts/affinage.pyz post-reply:
- Applied (with from-comment:<id> tag) โ "Fixed โ <applied summary>."
- Deferred (with from-comment:<id> tag) โ "Attempted fix reverted โ <reason>."
Fresh-window review¶
Detection โ read the chain signal, not the flags:
- Standalone: no upstream
handoff_contextis in scope (the user invoked/affinage <pr>directly). The PR diff has not been reviewed this session. - Chained: a
handoff_contextwithsource_skill: /cookor/cureis in scope./agealready reviewed this diff upstream.
Behaviour:
- Standalone (and
--no-agenot passed): run/age <pr-ref>over the PR diff. Fold each returned finding into the affinage report's severity sections tagged[from-age:<dimension>]. They flow to/curewith every other selected finding and get no GitHub reply โ there is no reviewer to notify, same as[from-check:โฆ]items. - Chained, or
--no-age: skip the pass. Re-running/ageon an already-reviewed diff double-grades.
Run the fresh /age before grading external claims so a comment that merely echoes an /age finding can be deduped. To keep the parent context lean, run the pass under the same sub-agent gate as grading (## Sub-agent context gate).
Merge-conflict resolution¶
When affinage.pyz pr-status reports merge.mergeable: CONFLICTING or merge.state: DIRTY, the PR cannot merge until conflicts are resolved. /affinage does not resolve conflicts by hand โ it routes to /melt, which runs the structural cascade (mergiraf โ rerere โ kdiff3).
- Materialise the conflicts locally:
gh pr checkout <pr>, thengit merge origin/<base>. (gh pr checkoutneither opens nor updates the PR, so it does not breach the no-/ghrule.) - Hand off to
/melt. It first checks for squash-merge residue and stops with remedies if found โ surface those verbatim and do not auto-apply. -
After
/meltresolves cleanly, the resolution commit is owned by/melt//cure. Pushing the merge follows/cure's push contract (push to the already-open PR after a clean cure). -
Default and
--automode: run the checkout +/meltautomatically before dispatching/cure, then re-runaffinage.pyz pr-statusto confirmmergeablecleared. If/meltcannot resolve (manual kdiff3 needed, or squash residue), writestatus: halt: merge-conflicts-need-humanand stop. --safemode: gate the checkout +/meltbehind the handoff prompt โ offer "Resolve merge conflicts" alongside the cure-selection options.
Sub-agent context gate¶
/affinage keeps dialogue, selection, approval state, and reply posting in the parent context. Spawn a read-only grading sub-agent only when the parent context would balloon:
- Total input count (comments + CI failures) exceeds 10.
- Diff exceeds ~25 KB.
- Threads span more than 5 files.
The sub-agent returns a digest: graded findings table with dimension, severity, grounded-evidence cite, and pre-drafted push-back text for any Reviewer-rejected items. The parent owns the report write, selection gate, /cure dispatch, and reply posting.
Digest size, parent-vs-sub-agent split, and harness-agnostic sub-agent selection live in skills/age/references/sub-agent-gate.md.
Preferred tools and fallbacks¶
Code search and reading go through cheez-* skills (/cheez-search, /cheez-read). Beyond cheez-* there are affinage-specific tools:
| Need | Prefer | Fallback |
|---|---|---|
| PR status (build + merge) | ${CLAUDE_SKILL_DIR}/scripts/affinage.pyz pr-status |
manual gh pr checks + gh pr view |
| GitHub fetch | gh api |
none (skill halts) |
| Reply posting | ${CLAUDE_SKILL_DIR}/scripts/affinage.pyz post-reply |
none โ direct gh api calls bypass the agent on behalf of <handle> attribution |
| Diff inspection | delta |
git diff --unified=3 |
Output¶
Write to .cheese/affinage/pr-<n>.md with the four-line handoff slug at the top, then the age-style body with two extra sections:
status: ok | halt: <one-line reason>
next: cure | done
artifact: <path-to-prior-cure-or-press-report-if-any>
<one-line orientation: what the PR does and what was graded>
# Affinage Report โ PR #<n>
## Orientation
<one or two factual sentences about the PR and what was graded>
## PR status
- Build: passing | failing (N jobs)
- Merge: clean | conflicts (resolved via /melt | needs human)
- Comments: K unresolved (M skipped as outdated)
- Fresh review: ran /age (N findings) | skipped (chained) | skipped (--no-age)
## Blocker
- **[from-comment:<id>] [security:blocker]** alice on `src/auth.ts:42` โ token parsed without validation.
- location: contract ยท fix-cost-now: contained ยท fix-cost-later: structural
- reviewer-asserted: changes-requested
- recommendation: validate `authorization` header; reject with 401 on missing.
- **[from-check:test-suite] [correctness:blocker]** CI job `test-suite` โ 3 tests failing in `tests/auth.test.ts`.
- location: contract ยท fix-cost-now: contained ยท fix-cost-later: structural
- recommendation: re-run after fixing the missing null check.
- **[from-check:build] [correctness:blocker]** CI job `build` โ `tsc` fails: `src/auth.ts:42: 'token' is possibly undefined`.
- location: contract ยท fix-cost-now: contained ยท fix-cost-later: structural
- recommendation: narrow `token` before use; build is red until this compiles.
- **[from-age:efficiency] [efficiency:high]** fresh review โ `src/api/users.ts:88` re-fetches the user inside the loop body.
- location: hot path ยท fix-cost-now: contained ยท fix-cost-later: contained
- recommendation: hoist the fetch above the loop.
## High
... (same shape)
## Medium
... (same shape)
## Low
- **[from-comment:<id>] [deslop:low]** copilot on `src/utils/format.ts:18` โ rename `data` to `lineItems` for clarity.
- location: class ยท fix-cost-now: contained ยท fix-cost-later: contained
- recommendation: rename `data` โ `lineItems`. Valid cheap nit โ fixed via `/cure`, not pushed back.
... (same shape; collapsible per --full rules)
## Needs-investigation
- **[from-comment:<id>]** bob on `src/api/users.ts:108` โ "might break analytics pipeline."
- reason: claim plausible but pipeline lives in a different repo; diff cannot confirm.
- suggested action: human reads `analytics-svc/consumers/users.ts`.
## Reviewer-rejected
- **[from-comment:<id>]** copilot on `src/auth.ts:30` โ "missing `await`; this promise is unhandled."
- reason: wrong โ `parseToken` is synchronous (returns `string`, not a `Promise`, see `src/auth.ts:12`); there is nothing to await.
- draft reply: "`parseToken` is synchronous here (returns `string`, `src/auth.ts:12`), so there's no promise to await. Leaving as-is."
- **[from-comment:<id>]** dana on `src/api/users.ts:60` โ "extract this into a generic repository layer."
- reason: valid but large โ fix-cost-now: sprawling (6 files across 2 slices); scope expansion beyond this PR.
- draft reply: "Agreed this would be cleaner, but it's a cross-slice refactor beyond this PR's scope โ filing a follow-up rather than growing this change."
## Confidence
<certain | speculating | don't know> โ <one-line justification>
## Next step
Auto-fixing the recommended set via `/cure` and posting the drafted replies (or, on a reason to ask / `--safe`, the selection prompt rendered inline โ pick findings to cure or `none` to stop).
Empty severity sections are omitted entirely. ## Needs-investigation and ## Reviewer-rejected are omitted when no items land there.
status: ok when grading completed; status: halt: <reason> when gh or pr-status.py failed in a way that blocks honest grading. next: cure when at least one finding meets the medium+ floor (medium-or-above, or a cheap contained-fix low); next: done when none do.
Handoff¶
Pipeline: culture โ mold โ cook โ press โ age โ cure โ ship ยท /affinage is parallel to /age and feeds the same /cure.
After the report lands, affinage acts by default and asks only on a genuine reason (a sprawling/structural fix in the recommended set, conflicting findings) or under --safe (Flow step 8). What it acts on depends on whether any severity-section finding exists.
When at least one severity-section finding exists (any severity, including Low) โ compute the recommended composite (all-medium, cheap). With no reason to ask and no --safe: announce the one-line selection, post the drafted non-cure replies (Flow step 9), dispatch /cure (below), and post the cure-dependent replies (step 10) on return. On a reason to ask or --safe: render the cure-selection table inline (per skills/cure/references/selection.md) and ask via shared/handoff-gate.md, pre-selecting the recommended composite and flagging heavy rows. Lead with the recommended composite, then present the four severity-floor options below it, in the same most-inclusive-to-least order, so the gate is predictable across every run:
- Fix mediums-and-above plus cheap lows (recommended) โ equivalent to
all-medium, cheap(floor at medium โ blockers + high + medium โ unioned with everyLowwhosefix-cost-now: contained; the small valid nits cheaper to fix than to defer). Sprawling/structural lows are left out. - Fix everything โ equivalent to
all(every finding regardless of severity). - Fix medium-severity and above โ equivalent to
all-medium(floor at medium: blockers + high + medium โ the severity-floor portion of themedium+auto-floor; addcheapto also union the contained-fix lows, i.e. the recommended composite above). - Fix high-severity and blockers โ equivalent to
all-high. - Fix blockers only (strict) โ equivalent to
all-blocker.
Then offer the non-floor options last:
- Pick findings to fix โ free-text reply using
/age//cureverbs (1,3,5,all-blocker,all-medium,all-high,cheap,all,none,skip N). - Resolve merge conflicts (offered only when the PR has conflicts) โ checkout +
/meltper## Merge-conflict resolution, then re-render this gate. - Stop โ leave the report for later โ equivalent to
none.
Present all four severity options on every run even when a severity band is empty: a floor that resolves to an empty set is a valid, predictable no-op โ do not drop or reorder options based on which bands happen to be populated. If the user selects a floor (or the recommended composite) that resolves to an empty set, treat the selection as none: report that no findings match and do not dispatch /cure with empty resolved_ids (the non-empty-selection dispatch rule below still holds).
When no severity-section finding exists but Reviewer-rejected or Needs-investigation has items โ /cure has nothing to act on, so skip it. By default, post all drafted replies (Flow step 9) and exit. Under --safe, render a reply-only gate first:
- Post all (recommended) โ post every drafted push-back and human-investigating note.
- Post pushbacks only โ post
Reviewer-rejecteddrafts; skipNeeds-investigationnotices. - Skip posting โ leave the report for later; post nothing.
- Per-finding โ free-text pick of which drafts to post.
On the selection (or the default post-all), post via Flow step 9 and exit with status: ok / next: done. This mirrors the documented auto-mode "no findings meet the floor" branch (see ### Auto mode).
On a non-empty cure selection (auto-selected by default or chosen at the gate), immediately dispatch /cure <slug> [--safe] [--open-pr] [--hard] with locked context:
handoff_context:
source_skill: /affinage
source_report: .cheese/affinage/pr-<n>.md
selection: "<verb or explicit ids>"
resolved_ids: [<expanded ids>]
/cure re-confirms cited ids and goes straight to apply. Propagate --safe, --open-pr, and --hard to /cure when in scope. /affinage resumes when /cure returns to post replies.
Auto mode¶
When invoked with --auto --stake <floor>:
- Skip the selection gate.
- If the PR has merge conflicts, resolve them via
/meltfirst (see## Merge-conflict resolution). If/meltcannot resolve, halt withstatus: halt: merge-conflicts-need-humanbefore any/curedispatch. - If standalone (and
--no-agenot passed), run the fresh/agepass so[from-age:โฆ]findings join the floor-based auto-selection. - Auto-select every finding (comment-sourced, CI-sourced, OR fresh-
/age-sourced) that meets the floor โ severity at or above the floor, plus cheap contained-fix lows when the floor ismedium+(same floor semantics as/cure). - Dispatch
/cure --auto --stake <floor>. - After
/cure --autoand its downstream/age --scope --autochain settle, post replies for the originally graded items only. Do NOT re-grade for findings discovered by/age --scope. - Reviewer-rejected items: post the pre-drafted push-back.
- Needs-investigation items: post the human-investigating reply.
/affinagedoes not invoke/ghitself. The PR push is owned by/cure's terminal contract: the final cure pass pushes to the already-open PR (and, with--open-pr, may open a new one). Propagate--open-prto/cure --autowhen it is in scope.
The whole cure chain (cure โ /age --scope --auto โ up to the two-cure-pass cap) must run in the parent affinage context so the post-cure reply step still has the original graded findings (slug, ids, from-comment:<id> tags, drafted push-back text) in memory. Same in-session-memory contract as /age --auto's two-pass cap. Spawning the cure chain in a sub-agent silently breaks reply posting โ do not.
If no findings meet the floor, skip the /cure dispatch, post replies for Reviewer-rejected + Needs-investigation items only, and exit with status: ok / next: done / "no findings meet <floor>".
--hard mode¶
/affinage does not fire the /hard-cheese gate. It propagates --hard forward to /cure so the gate can fire at the share-for-review boundary inside /cure --hard. See skills/cure/SKILL.md --hard mode.
Rules¶
- Grading is code-grounded, not reviewer-asserted.
CHANGES_REQUESTEDis metadata, not a severity bump. - Prefer fixing over pushing back. A valid, grounded nit whose fix is contained (
fix-cost-now: containedโ a few lines or a localized refactor) goes to/cureas aLowfinding tagged[from-comment:<id>]; do not draft a push-back for it. Reserve## Reviewer-rejectedfor claims that are wrong/ungrounded or whose fix is a lot of work (moderate/sprawling/structural). Seeskills/age/references/voice.md. - Never auto-apply fixes from
/affinageitself. Code fixes go through/cure; merge conflicts go through/melt. - Fresh
/ageruns only on standalone invocations (no upstreamhandoff_context) and only when--no-ageis absent. Chained runs never re-review the diff. - Merge conflicts are resolved through
/melt, not by hand.gh pr checkoutto materialise conflicts is allowed โ it neither opens nor updates the PR. Pushing the resolved merge follows/cure's push contract (push to the already-open PR after a clean cure);--safere-gates it. - Every posted reply ends with the literal
agent on behalf of <handle>attribution via${CLAUDE_SKILL_DIR}/scripts/affinage.pyz post-reply, where<handle>is resolved fromRESPOND_GH_HANDLEโgh api user --jq .loginโgit config user.name. Never callgh apidirectly to post. - Idempotent re-runs: skip threads where the latest comment is from the resolved handle. The REST
/commentsendpoint does not expose thread resolution, so honest idempotency relies on the latest-comment-from-self heuristic; switch to GraphQLreviewThreadsif cross-session resolution-state visibility becomes required. - CI-sourced findings get no reply (no reviewer to notify).
/affinagenever invokes/ghitself. The PR push happens inside/cureafter a clean cure (push to the already-open PR by default;--open-propens a new one;--safere-gates).- Apply the shared voice kernel (
skills/age/references/voice.md): name confidence ascertain | speculating | don't know; agree when no findings warrant grading.
References¶
skills/age/SKILL.mdโ review pipeline, dimensions, sub-agent gate, report shape.skills/age/references/dimensions.mdโ per-dimension rubrics and severity computation.skills/cure/SKILL.mdโ apply pipeline,--auto --stakefloors, handoff context shape.skills/cure/references/selection.mdโ selection verbs and composition.skills/melt/SKILL.mdโ merge-conflict resolution cascade (mergiraf โ rerere โ kdiff3).shared/handoff-gate.mdโ gate primitives.${CLAUDE_SKILL_DIR}/scripts/affinage.pyz post-replyโ reply posting withagent on behalf of <handle>attribution.${CLAUDE_SKILL_DIR}/scripts/affinage.pyz pr-statusโ PR status fetcher.