Skip to content

orb(review): generated SKILL.md contradicts itself on whether a linked issue is required #9671

Description

@JSONbored

⚠️ 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:106Requires 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

  • hasStrictLinkedIssueRule in src/review/repo-skill-render.ts returns false for a profile
    with requireLinkedIssue: true, linkedIssuePolicy: "required", linkedIssueGateMode: "advisory",
    and true when linkedIssueGateMode: "block" — asserted by a new named case in
    test/unit/repo-skill-render.test.ts.
  • A named regression test renders the full SKILL.md for the advisory-mode profile above and asserts
    the body does NOT contain "A linked issue is required" while it DOES contain "Required: no".
  • A test renders the block-mode profile and asserts both the trigger sentence and "Required: yes"
    are present (the two agree in both directions).
  • A test asserts shouldGenerateRepoSkill no longer counts the linked-issue signal for the
    advisory-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-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

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:bugGittensor-scored bug fix — scores a 0.05x multiplier.help wantedExtra attention is needed

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions