⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.
Context
RepoProfileContributionWorkflow names the authority explicitly
(src/review/repo-profile.ts:68-70):
linkedIssueGateMode — The actual enforcement authority for whether a missing linked issue blocks a
PR — requireLinkedIssue alone does not block (see its doc comment on RepositorySettings); only
"block" does.
src/review/repo-skill-render.ts uses two different fields for the same assertion, in the same
generated file:
function hasStrictLinkedIssueRule(contributionWorkflow: RepoProfileContributionWorkflow): boolean {
return contributionWorkflow.requireLinkedIssue && contributionWorkflow.linkedIssuePolicy !== "optional"; // :27
}
…
if (hasStrictLinkedIssueRule(contributionWorkflow))
reasons.push(`- A linked issue is required, with a "${contributionWorkflow.linkedIssuePolicy}" policy.`); // :73
…
- Required: ${contributionWorkflow.linkedIssueGateMode === "block" ? "yes" : "no"} // :121
So for a repo with requireLinkedIssue: true, linkedIssuePolicy: "required", and
linkedIssueGateMode: "advisory" (a real and common combination — advisory is the default for
linkedIssueGateMode, see src/rules/advisory.ts:1290), the generated SKILL.md says
"A linked issue is required, with a 'required' policy." a few lines above "Required: no".
This file is written into contributor repos as .claude/skills/contributing-to-<repo>/SKILL.md
(src/review/repo-skill-render.ts:66) and is read by AI coding agents, so the contradiction is
directly actionable misinformation.
The sibling renderer already uses the right field for the identical assertion:
src/review/repo-doc-render.ts:106 — Requires a linked issue: ${contributionWorkflow.linkedIssueGateMode === "block" ? "yes" : "no"}.
hasStrictLinkedIssueRule is also one of the three signals in shouldGenerateRepoSkill's
2-of-3 threshold (src/review/repo-skill-render.ts:38), so a repo can get a skill file generated off
a signal that enforces nothing.
Requirements
hasStrictLinkedIssueRule must key on contributionWorkflow.linkedIssueGateMode === "block" — the
documented enforcement authority — matching src/review/repo-doc-render.ts:106.
renderTriggerReasons' emitted sentence must state the mode that actually blocks, and must not claim
a linked issue is "required" for a repo whose linkedIssueGateMode is not "block".
- The Linked-issues section at
src/review/repo-skill-render.ts:121 must stay as-is (it is already
correct) — the two must agree after the fix.
linkedIssuePolicy may still be REPORTED in the generated text; it must no longer DECIDE the
assertion.
- No change to
RepoProfileContributionWorkflow, repo-profile.ts, or repo-doc-render.ts.
⚠️ Required pattern: src/review/repo-doc-render.ts:106, which makes the identical assertion from
linkedIssueGateMode. What does NOT satisfy this issue: changing the Linked-issues section at
:121 to match the trigger sentence; introducing a third derived boolean; keeping both fields in a
compound condition; or "resolving" the contradiction by deleting the trigger sentence rather than
making it correct.
Deliverables
All Deliverables above are required in a single PR. A PR that satisfies only some of them — for
example changing the field in hasStrictLinkedIssueRule (Deliverable 1) without the rendered-body
regression test (Deliverable 2) — does not resolve this issue.
Test Coverage Requirements
This repo enforces 99%+ Codecov patch coverage, branch-counted, and vitest.config.ts's
coverage.include covers src/**/*.ts — this file is measured. Both arms of the changed condition
need a test ("block" and a non-block mode), and both arms of shouldGenerateRepoSkill's threshold as
affected by this signal.
Expected Outcome
A generated SKILL.md never tells a contributor's coding agent that a linked issue is required while
its own Linked-issues section says it is not, and the skill file is only generated when the
linked-issue signal reflects a rule that actually blocks.
Links & Resources
src/review/repo-skill-render.ts:23-30, :70-76, :118-122
src/review/repo-doc-render.ts:100-110 (the correct sibling)
src/review/repo-profile.ts:66-71 (the documented authority)
test/unit/repo-skill-render.test.ts
Context
RepoProfileContributionWorkflownames the authority explicitly(
src/review/repo-profile.ts:68-70):src/review/repo-skill-render.tsuses two different fields for the same assertion, in the samegenerated file:
So for a repo with
requireLinkedIssue: true,linkedIssuePolicy: "required", andlinkedIssueGateMode: "advisory"(a real and common combination — advisory is the default forlinkedIssueGateMode, seesrc/rules/advisory.ts:1290), the generatedSKILL.mdsays"A linked issue is required, with a 'required' policy." a few lines above "Required: no".
This file is written into contributor repos as
.claude/skills/contributing-to-<repo>/SKILL.md(
src/review/repo-skill-render.ts:66) and is read by AI coding agents, so the contradiction isdirectly actionable misinformation.
The sibling renderer already uses the right field for the identical assertion:
src/review/repo-doc-render.ts:106—Requires a linked issue: ${contributionWorkflow.linkedIssueGateMode === "block" ? "yes" : "no"}.hasStrictLinkedIssueRuleis also one of the three signals inshouldGenerateRepoSkill's2-of-3 threshold (
src/review/repo-skill-render.ts:38), so a repo can get a skill file generated offa signal that enforces nothing.
Requirements
hasStrictLinkedIssueRulemust key oncontributionWorkflow.linkedIssueGateMode === "block"— thedocumented enforcement authority — matching
src/review/repo-doc-render.ts:106.renderTriggerReasons' emitted sentence must state the mode that actually blocks, and must not claima linked issue is "required" for a repo whose
linkedIssueGateModeis not"block".src/review/repo-skill-render.ts:121must stay as-is (it is alreadycorrect) — the two must agree after the fix.
linkedIssuePolicymay still be REPORTED in the generated text; it must no longer DECIDE theassertion.
RepoProfileContributionWorkflow,repo-profile.ts, orrepo-doc-render.ts.Deliverables
hasStrictLinkedIssueRuleinsrc/review/repo-skill-render.tsreturnsfalsefor a profilewith
requireLinkedIssue: true,linkedIssuePolicy: "required",linkedIssueGateMode: "advisory",and
truewhenlinkedIssueGateMode: "block"— asserted by a new named case intest/unit/repo-skill-render.test.ts.the body does NOT contain "A linked issue is required" while it DOES contain "Required: no".
are present (the two agree in both directions).
shouldGenerateRepoSkillno longer counts the linked-issue signal for theadvisory-mode profile (i.e. a repo with only advisory linked-issue + multi-stage CI does not reach
the 2-of-3 threshold).
All Deliverables above are required in a single PR. A PR that satisfies only some of them — for
example changing the field in
hasStrictLinkedIssueRule(Deliverable 1) without the rendered-bodyregression test (Deliverable 2) — does not resolve this issue.
Test Coverage Requirements
This repo enforces 99%+ Codecov patch coverage, branch-counted, and
vitest.config.ts'scoverage.includecoverssrc/**/*.ts— this file is measured. Both arms of the changed conditionneed a test (
"block"and a non-block mode), and both arms ofshouldGenerateRepoSkill's threshold asaffected by this signal.
Expected Outcome
A generated
SKILL.mdnever tells a contributor's coding agent that a linked issue is required whileits own Linked-issues section says it is not, and the skill file is only generated when the
linked-issue signal reflects a rule that actually blocks.
Links & Resources
src/review/repo-skill-render.ts:23-30,:70-76,:118-122src/review/repo-doc-render.ts:100-110(the correct sibling)src/review/repo-profile.ts:66-71(the documented authority)test/unit/repo-skill-render.test.ts