Skip to content

Enforce issue dependencies: a derived blocked label, an assignment guard and a required pull-request check #1034

Closed

Description

@cemililik

Summary

Work that depends on other work is recorded only in prose today ("after S8", "Settle #706 first", "don't start without coordinating on #894"). Nothing stops a contributor from claiming or opening a pull request for an issue whose prerequisite is still open, and nothing tells them when it opens up. This issue turns dependencies into an enforced contract.

What exists today

  • GitHub's native Blocked by links mark an issue as blocked in the sidebar, the Issues list and the project board, but they cannot be filtered (is:blocked returns nothing), they do not reach the project views or the good first issue page, and no workflow event fires when a link is added or removed.
  • tools/assign_on_comment.py refuses deferred, security, needs-triage, epic and phase: 16 issues, but knows nothing about dependencies.
  • No pull-request check looks at the issues a pull request links.

Design

  1. Source of truth: native Blocked by links, set by a maintainer in the issue's sidebar. A dependency written only in prose does not count.
  2. A blocker is resolved only when it is closed as completed. A blocker closed as not planned or as a duplicate did not deliver what the dependent waits for, so the dependent stays blocked, gets needs-triage and one comment asking a maintainer to re-plan it.
  3. blocked is a derived label, never set by hand: a sync job adds it to every open issue with an unresolved blocker and removes it everywhere else. It runs when an issue is closed or reopened, hourly as a backstop for link edits, and on demand. When it removes the label from an issue that was waiting, it posts one comment; no comment when an issue becomes blocked.
  4. Contributor gates: /assign refuses a blocked issue and says why; a pull-request check, Issue dependencies, fails while an issue the pull request links (Fixes / Closes / Resolves / Refs #N) is blocked, unless the same pull request closes every open blocker (in the form GitHub closes on merge) or a maintainer labels it dependency-override (the label set by anyone else is ignored). The check runs on pull_request_target, so both the workflow and the script come from the default branch and no pull-request code is checked out. Every sync run also re-runs the check of each open pull request whose last result no longer matches its linked issues.
  5. Views: the project gets a Blocked view; Front door and Small tasks hide blocked issues.

Dependencies recorded with this change

From a review of all open issues (bodies and comments; the prose matches that describe code behaviour, such as "the digest depends on whether xxhash is installed", are not dependencies):

Acceptance criteria

  • tools/issue_dependencies.py (sync, check-pr) and its tests; the decision rules are pure functions, the GitHub calls are injected and limited to fixed endpoints.
  • .github/workflows/issue-dependencies.yml and .github/workflows/pr-dependencies.yml, least privilege, pinned actions, no ${{ }} in a run: line; tests pin these properties.
  • /assign refuses a blocked issue (label or an open native blocker), with a test.
  • CONTRIBUTING (labels table, Working on an issue, required checks), CLAUDE.md / AGENTS.md and the CHANGELOG describe the rule.
  • Labels blocked and dependency-override exist; the dependencies above are recorded as native links and the labels match them.
  • After merge, before 2026-11-02: a repository Actions policy allows pull_request_target for .github/workflows/pr-dependencies.yml only (POST /repos/HodeTech/ForgeLM/actions/policies); GitHub blocks that event in public repositories by default from that date, and the check would stop reporting.
  • After merge: the Issue dependencies check is seen attached to a pull request's head commit (it runs on pull_request_target), then added to the required checks of development, and CONTRIBUTING's "not yet among the required checks" sentence is removed.

Activity

  1. added
    enhancementNew feature or request
    severity: lowMinor defect, inaccuracy or rough edge
    wave: 4Roadmap wave 4: low / info / watch, when touching the module
    on Oct 20, 2026
  2. moved this from Todo to In progress in ForgeLM Project Planon Oct 20, 2026
  3. cemililik commented on Oct 20, 2026

    @cemililik
    CollaboratorAuthor

    Reopening: the merge of #1035 closed this through the first commit's Fixes #1034, but the post-merge criteria are still open (the Actions policy for pull_request_target, the required check and the CONTRIBUTING sentence). The pull request that finishes them will close it.

  4. added 2 commits that reference this issue on Oct 20, 2026
    760f712
    78026eb
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

    area: dev-toolingCode area: dev-toolingenhancementNew feature or requestseverity: lowMinor defect, inaccuracy or rough edgewave: 4Roadmap wave 4: low / info / watch, when touching the module

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions