Skip to content

Dependency Management

Itervox treats dependencies as dispatch eligibility and observable audit state. It does not implement a full DAG scheduler and it does not mutate tracker state from the core audit path.

Blockers come from native issue relations — inverse relations of type blocks — and from sub-issues: a parent with open children is blocked by them.

Blockers are text-derived from the issue body. GitHub comments are not parsed.

Matched phrases: blocked by, blocked on, depends on, depends upon, requires, waiting on, waiting for — each followed by one or more #123 references.

FormExampleCaptured
List separatorsdepends on #3, #4 and #5 / depends on #3 & #4#3 #4 #5
Optional colonDepends on: #3#3
Bullet list across newlinesDepends on:
- #3
- #4
#3 #4
Cross-repo mid-listdepends on #3, foo/bar#4, #5#3 #5

A blank line, or a non-bullet non-reference line, ends the list. Only same-repo #N references become blocker edges — a cross-repo reference is recognized and skipped, never matched as a blocker itself.

Casual phrasing such as requires #5 to be reviewed also matches. That is deliberate: under-capturing a real dependency is worse than occasionally holding an issue an operator can unblock explicitly.

A 51st sub-issue (Linear children(first: 50)) is invisible and fails open — the parent stays dispatchable rather than being held on data itervox cannot see.

The dependency audit exposes labels such as tracker_relation and issue_text so operators can see where blocker data came from.

An issue with unresolved blockers is not eligible for normal dispatch. A queued automation blocked by dependencies stays queued with a blocked_by reason until every blocker is observed as terminal.

Unknown blocker state is not treated as resolved. A paused blocker is still unresolved; pausing only stops local work, it does not prove the blocker is terminal. The dependent issue remains blocked until the tracker adapter can prove the blocker is terminal. GitHub’s missing/deleted referenced issue fallback maps that blocker to closed, matching the GitHub adapter behavior.

Merged PRs do not unblock dependents by themselves. Itervox waits until the blocking issue itself is observed as terminal, closed, or done by the tracker.

Audit rows record:

  • current issue state
  • blocked, unblocked, or unknown status
  • all blockers, unresolved blockers, and resolved blockers
  • dependency source labels
  • first blocked time, last audit time, and unblock transition metadata

When an issue moves from blocked or unknown-with-blockers to unblocked, Itervox records a blockers_resolved transition version.

The audit is not startup-only. On each poll and manual refresh, the event loop refreshes known audit rows, including rows for issues outside active states and outside blockers_resolved source filters. If tracker data changes and a blocker becomes terminal, the next refresh updates the audit row, Deps graph, automation queue eligibility, and any matching blockers_resolved transition.

Core audit is read-only. Moving a tracker issue requires an opt-in automation and a profile with move_state.

automations:
- id: unblock-backlog-to-todo
trigger:
type: blockers_resolved
filter:
states_any: ["backlog", "Backlog"]
profile: pm
policy:
move_to_state: "Todo"
instructions: |
All tracked blockers for this backlog issue are terminal.
Move only backlog/Backlog issues to Todo.
Do not move review, in-review, PR-open, or merged issues.

The default source-state filter is intentionally limited to backlog / Backlog. Review, in-review, PR-open, merged, and closed states are excluded from the release-safe example.

The selected profile must include move_state in allowed_actions. Without that permission, it can comment/report readiness but cannot move tracker state through daemon actions.

Itervox keeps ordering simple: unresolved blockers make dependents ineligible; after blockers resolve, normal dispatch uses priority, created time, and identifier. Automation queue drain preserves FIFO queue order after eligibility is satisfied.