You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GitHub-native Factory overloads safety.requireLabel (for example, factory-ready) as both:
the intake signal for new work, and
a precondition for operating on work already in factory:in-progress.
That makes a normal human action — removing factory-ready to mean “do not pick this up as new work” — silently strand existing state. The live repro is AgentWorkforce/hoopsheet#32, which has remained factory:in-progress without factory-ready for 11 days.
Evidence and the initial two-site finding come from head-of-experiments’ hoopsheet/factory survey. They also tested the obvious ownership-scoping objection: requireLabel is not what scopes a Factory instance to repositories. Repo routing is handled separately through repos.names / repos.byLabel (#repoLabelForGithubIssue and its githubIssueMirrorsSkippedUnroutable path). Separating intake from lifecycle state does not weaken repository ownership.
Code sweep
An exhaustive rg sweep of requireLabel across src/ found the following GitHub lifecycle sites in src/orchestrator/factory.ts that incorrectly depend on the intake label after work is already in progress:
runOnce() builds mayRecoverGithubOrphan only when both the required intake label and factory:in-progress are present (around 1738).
#reconcileOrphanedGithubInProgress() repeats the same precondition (around 1907).
#isGithubIssueResumable() repeats it again (around 4050), so the issue is unresumable as well as unreconcilable.
#clarificationIssueStillActive() treats an in-progress issue as inactive when the intake label was removed (around 12668), cancelling durable clarification wake.
Other requireLabel uses are legitimate intake/scope checks (#isIssueReady, live change ingestion, dispatch safety, routing-label exclusion) and should remain intake-driven.
Expected behavior
New-work discovery and dispatch should continue to require safety.requireLabel.
Lifecycle recovery, resume, clarification wake, and discovery of already-owned lifecycle state should key on factory:in-progress (plus terminal/closed and active-owner guards), not on the intake label.
The indexed discovery path must include nonterminal Factory lifecycle labels needed for reconciliation, even when the intake label is absent.
Removing the intake label must not erase or disable cleanup of existing Factory state.
Fix direction
Introduce distinct predicates for:
intake eligible: open + configured required label + not terminal/in-progress as appropriate;
Factory lifecycle active/recoverable: open + factory:in-progress + not factory:human-review, with the existing durable-owner/roster safety checks.
Use the lifecycle predicate consistently in orphan discovery, reconciliation, resume, and clarification wake. Add regression coverage for an open factory:in-progress issue without factory-ready, including the _index.json fast path.
Problem
GitHub-native Factory overloads
safety.requireLabel(for example,factory-ready) as both:factory:in-progress.That makes a normal human action — removing
factory-readyto mean “do not pick this up as new work” — silently strand existing state. The live repro isAgentWorkforce/hoopsheet#32, which has remainedfactory:in-progresswithoutfactory-readyfor 11 days.Evidence and the initial two-site finding come from head-of-experiments’ hoopsheet/factory survey. They also tested the obvious ownership-scoping objection:
requireLabelis not what scopes a Factory instance to repositories. Repo routing is handled separately throughrepos.names/repos.byLabel(#repoLabelForGithubIssueand itsgithubIssueMirrorsSkippedUnroutablepath). Separating intake from lifecycle state does not weaken repository ownership.Code sweep
An exhaustive
rgsweep ofrequireLabelacrosssrc/found the following GitHub lifecycle sites insrc/orchestrator/factory.tsthat incorrectly depend on the intake label after work is already in progress:runOnce()buildsmayRecoverGithubOrphanonly when both the required intake label andfactory:in-progressare present (around 1738).#reconcileOrphanedGithubInProgress()repeats the same precondition (around 1907).#isGithubIssueResumable()repeats it again (around 4050), so the issue is unresumable as well as unreconcilable.#clarificationIssueStillActive()treats an in-progress issue as inactive when the intake label was removed (around 12668), cancelling durable clarification wake.#githubIssuePathsFromIndex()only enumerates open issues carrying the intake label (around 4519). On the current indexed fast path, an orphan like Live factory start should always run startup backfill after subscribing #32 can disappear before the reconciler sees it at all.Other
requireLabeluses are legitimate intake/scope checks (#isIssueReady, live change ingestion, dispatch safety, routing-label exclusion) and should remain intake-driven.Expected behavior
safety.requireLabel.factory:in-progress(plus terminal/closed and active-owner guards), not on the intake label.Fix direction
Introduce distinct predicates for:
factory:in-progress+ notfactory:human-review, with the existing durable-owner/roster safety checks.Use the lifecycle predicate consistently in orphan discovery, reconciliation, resume, and clarification wake. Add regression coverage for an open
factory:in-progressissue withoutfactory-ready, including the_index.jsonfast path.