-
Notifications
You must be signed in to change notification settings - Fork 0
fix(factory): recover orphaned in-progress issues that are in scope by title (#139) #327
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2931,12 +2931,13 @@ export class FactoryLoop implements Factory { | |
| const labels = isGithubIssue(issue) | ||
| ? new Set(issue.labels.map((label) => label.trim().toLowerCase())) | ||
| : undefined | ||
| const requiredLabel = this.#config.safety.requireLabel.trim().toLowerCase() | ||
| // Must stay the same scope test as dispatch and as | ||
| // #reconcileOrphanedGithubInProgress. Gating on the scope label alone | ||
| // left every title-scoped issue stuck in `factory:in-progress` forever. | ||
| const mayRecoverGithubOrphan = !wasReady && | ||
| !dryRun && | ||
| issueSource === 'github' && | ||
| Boolean(requiredLabel) && | ||
| Boolean(labels?.has(requiredLabel)) && | ||
| isInFactoryScope(issue, this.#config.safety) && | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For the newly admitted case—an issue with only a title prefix and Useful? React with 👍 / 👎. |
||
| Boolean(labels?.has('factory:in-progress')) && | ||
| !labels?.has('factory:human-review') | ||
| if (!mayRecoverGithubOrphan) { | ||
|
|
@@ -3568,10 +3569,14 @@ export class FactoryLoop implements Factory { | |
| if (!context) return { recovered: false, reason: 'orphan-recovery safety context is unavailable' } | ||
| if (!isGithubIssue(issue)) return { recovered: false, reason: 'issue is not GitHub-native' } | ||
| const labels = new Set(issue.labels.map((label) => label.trim().toLowerCase())) | ||
| const required = this.#config.safety.requireLabel.trim().toLowerCase() | ||
| // Recovery must admit exactly what dispatch admits. Dispatch accepts the | ||
| // configured title prefix OR the scope label (`isInFactoryScope`), but this | ||
| // gate used to demand the label alone — so an issue admitted by its title | ||
| // could be dispatched and then never un-stuck, keeping `factory:in-progress` | ||
| // forever once its dispatch died. factory#139 is the live instance: title | ||
| // `[factory] ...`, and its only label is `factory:in-progress`. | ||
| if ( | ||
| !required || | ||
| !labels.has(required) || | ||
| !isInFactoryScope(issue, this.#config.safety) || | ||
| !labels.has('factory:in-progress') || | ||
| labels.has('factory:human-review') | ||
| ) return { recovered: false, reason: 'issue is not an orphan-recovery candidate' } | ||
|
|
@@ -7175,7 +7180,16 @@ export class FactoryLoop implements Factory { | |
| !labels.every((label) => typeof label === 'string')) { | ||
| return undefined | ||
| } | ||
| if (state !== 'open' || !labels.some((label) => label.trim().toLowerCase() === requiredLabel)) { | ||
| // Retain Factory's own lifecycle rows even when they lack the scope | ||
| // label. The index carries no title, so a title-scoped issue cannot be | ||
| // recognised here — and dropping it means its file is never read and the | ||
| // orphan-recovery sweep never sees it. `factory:in-progress` is a label | ||
| // only Factory applies, so a row carrying it is by definition | ||
| // Factory-touched and worth reading; `isInFactoryScope` downstream | ||
| // remains the authority on whether anything may be done with it. | ||
| const rowLabels = labels.map((label) => label.trim().toLowerCase()) | ||
| if (state !== 'open' || | ||
| !(rowLabels.includes(requiredLabel) || rowLabels.includes('factory:in-progress'))) { | ||
| continue | ||
| } | ||
| paths.push(`${GITHUB_ISSUE_ROOT}/${owner}__${repo}/issues/by-id/${number}.json`) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When Relayfile provides a valid
_index.json,#githubIssuePathsFromIndexfilters out every open row that lackssafety.requireLabel(lines 7168-7184), so a title-scoped orphan whose only label isfactory:in-progressis never read and this widened recovery gate never executes. The added test omits the index and therefore exercises only the full-tree fallback; indexed production deployments still leave the reported issue stranded. The index filtering must also retain in-progress title-scoped candidates, or fall back to the tree when such candidates cannot be identified from the index.Useful? React with 👍 / 👎.