flow-workflows 0.90.0 → 0.91.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,7 +17,7 @@ Every `$flow-*` command assumes these rules. They are stated once, here, so a co
17
17
  carries what is specific to its phase. Read this once per session; a command that says "load
18
18
  `flow-core`" means this file.
19
19
 
20
- **This file belongs to flow `0.90.0`.** Compare it once, at the start of the session, against
20
+ **This file belongs to flow `0.91.0`.** Compare it once, at the start of the session, against
21
21
  `version` in `~/.claude/flow/.claude-plugin/plugin.json`. The two differing means the session
22
22
  is running a **mixture** — the commands from one copy of the plugin, these shared rules from another
23
23
  — which is exactly what happens when a branch or a release candidate is loaded over an installed
@@ -244,11 +244,12 @@ configuration; these orders are the whole interface, and nothing else about the
244
244
  assumed:
245
245
 
246
246
  ```
247
- <cmd> why → start | study | answer | review | pipeline | merged
247
+ <cmd> why → start | study | answer | review | pipeline | merged | conflict
248
248
  <cmd> ticket --json → {number, title, body, comments[{author, at, text}], base, kind}
249
249
  <cmd> answer → one option's exact text, or free text; exit 2 = no reply
250
250
  <cmd> events --json → {"comments":[{thread,kind,id,author,at,body,url,path?,line?}]}
251
251
  | {"sha":…, "failed":[{name,conclusion,url,log_tail}]}
252
+ | {"conflict":{"base":…, "base_sha":…}}
252
253
  <cmd> ask --question-file F --options-file F [--recommended N] [--free-text] [--gate NAME]
253
254
  <cmd> publish --title-file F --body-file F [--part N --of M]
254
255
  <cmd> blocked --reason-file F
@@ -308,7 +309,7 @@ run has.
308
309
  runs the study phases as any run does, and three rules make it stop where it should:
309
310
 
310
311
  - **The door to code.** The first step of `$flow-feat-build` and `$flow-bug-fix` pre-flight, in
311
- `unattended`, re-reads `<cmd> why`: `start`, `answer`, `merged`, `review` or `pipeline` → go on;
312
+ `unattended`, re-reads `<cmd> why`: `start`, `answer`, `merged`, `review`, `pipeline` or `conflict` → go on;
312
313
  `study` → the study ends here; anything else, or the order failing → `blocked`. Every path from a
313
314
  study to code crosses that door, an answered question that resumes straight into `build`
314
315
  included, so the phases before it carry no clause. The run kind is read there, never stored: the
@@ -351,6 +352,7 @@ person asking for changes, a ticket that already has code — is `$flow-work-run
351
352
  | The next MR/PR of a train (`ship` close) | record — not started: one MR/PR per unattended run |
352
353
  | `build` with no startable MR/PR (its `depends_on` not `merged` in `meta.json`) | blocked — the reason names what must merge; an unattended `build` never stacks a branch on another, and never creates a remote branch |
353
354
  | The parent of a stacked MR/PR merged — rebase and force-push | blocked — never force-push unattended |
355
+ | Integrating the base into the MR/PR's branch (`green`) | on `why = conflict`, record — `git merge origin/<base>` as the orchestrator left it, never rebase, each conflict resolved on its merits (`$flow-work-green` §5.C); on any other `why`, blocked — the orchestrator brings the base in |
354
356
  | Any offer about the work's own bookkeeping — a tracker issue, the first `KNOWLEDGE.md` or a knowledge save, a FLOW convention, an agent lesson or a saved specialist, the follow-up survey, carrying files over from the main checkout, a contract handoff, archiving the work | record — `Later`; nothing written outside the work folder |
355
357
  | A step the command cannot complete (a red suite it cannot fix, a tool missing, auth failing, the same check failing a second time) | blocked |
356
358
  | Anything `auto` already decides on its own (size, flow mechanics, WIP commits, the next command) | as `auto` |
@@ -45,19 +45,34 @@ Read `~/.claude/flow/CORE.codex.md` first (shared rules: `FLOW.md` step 0, model
45
45
  4. **Integrating the base branch** — any `git merge`/`git rebase` of `git.default_base` into the branch, and any history rewrite or force-push it implies (§5.C).
46
46
  5. **Green-washing — NEVER, in any mode:** no rerun of a failed check hoping it passes; never disable, skip, `@skip`/`xit`, loosen a threshold, or delete a test/lint rule to force green; never resolve a conflict by blindly taking one side (`--ours`/`--theirs`, `checkout --theirs`, discarding the base's changes) — resolve by understanding both sides.
47
47
 
48
- **In `unattended`** (flow-core §2.1) — launched by `$flow-work-run` on `why = pipeline` — this
49
- command asks nothing and never touches the forge. Gate 5 holds exactly as written; the others
50
- resolve this way:
48
+ **In `unattended`** (flow-core §2.1) — launched by `$flow-work-run` on `why = pipeline` or
49
+ `why = conflict` — this command never touches the forge. Gate 5 holds exactly as written; the
50
+ others resolve this way:
51
51
 
52
52
  - **§1–§2** — no MR/PR is resolved and no forge is read: the failures are `<cmd> events --json` →
53
53
  `{"sha", "failed": [{name, conclusion, url, log_tail}]}`, and `log_tail` is the evidence. The order
54
54
  failing → `blocked`; `failed` empty → `done`, the summary saying so. `sha` not `HEAD` → `blocked`:
55
55
  the result is about another commit, and fixing it here would be fixing a guess.
56
+ On `why = conflict` the events are `{"conflict": {"base", "base_sha"}}` instead: the MR/PR
57
+ conflicts with `base`, which the orchestrator left in the checkout as `origin/<base>` at
58
+ `base_sha`. That is the only blocker of the round — category C, nothing to triage. `origin/<base>`
59
+ missing or not at `base_sha` → `blocked`: the run would merge a base nobody named.
56
60
  - **§3** — triage as written, recorded in `09-ci.md`. **K** (flaky / infra) → `blocked` with the
57
61
  evidence: the run has no rerun order, and the orchestrator owns reruns and the red-round limit.
58
- **C** (conflict, behind base) and anything needing a rebase or force-push → `blocked`: the
59
- orchestrator brings the base in. A **human** blocker → `blocked`, naming who. **S** → fixed within
62
+ **C** (conflict, behind base) on `why = pipeline`, and anything needing a rebase or force-push →
63
+ `blocked`: the orchestrator brings the base in, and relaunches with `why = conflict` when it
64
+ conflicts. A **human** blocker → `blocked`, naming who. **S** → fixed within
60
65
  scope, otherwise `blocked` with the justification.
66
+ - **§5.C on `why = conflict`** — gate 4 is recorded (`unattended:integrate-base`), never asked:
67
+ the orchestrator launched the run for exactly this. No fetch: the base is `origin/<base>` as the
68
+ orchestrator left it, never `git.default_base` read from the config. Always `git merge
69
+ origin/<base>`, never a rebase. Each conflict is resolved on its merits as step 3 says; step 6's
70
+ "intent of either side unclear" → `git merge --abort`, then question `decision` when the two
71
+ sides want things that contradict each other (a product decision: which intent wins), `blocked`
72
+ otherwise. The base it merges goes into this round of `09-ci.md` before the merge starts; the
73
+ answer re-enters at §5.C, reads the base there, and merges again from `origin/<base>` — an
74
+ unfinished merge does not survive the run. Step 4's design change that is more than a tweak →
75
+ `blocked`. The merge commit, after the full local gate, is the round's commit.
61
76
  - **§5** — fixes and the local verification as written; a local gate it cannot get green →
62
77
  `blocked`. A fix adding behaviour gets its brief recorded, not asked; a fix that needs a schema
63
78
  change, a design invalidation that is more than a tweak, or a high-severity finding from the
@@ -36,7 +36,7 @@ of truth, and an argument that disagrees with it is ignored and named in the log
36
36
  other mode a person is the router (`$flow-next`).
37
37
  - `autonomy.orchestrator_cmd` empty → flow-core §2.1: no phase runs.
38
38
  - Run `<cmd> why`. It fails, or prints anything but `start`, `study`, `answer`, `review`,
39
- `pipeline` or `merged` → print what it returned and its stderr in the §3 header and end. No closing order: an
39
+ `pipeline`, `merged` or `conflict` → print what it returned and its stderr in the §3 header and end. No closing order: an
40
40
  orchestrator that cannot say why it launched the run cannot take one either.
41
41
  - Run `<cmd> ticket --json` and keep `number`, `title`, `base` and `kind` (`kind` absent or `null` → `feat`: the tracker could not tell, so flow decides). `kind` is re-read on every run; only a run that starts the work uses it — once the work exists, its folder says feat or bug.
42
42
  It fails or prints no `number` → `blocked` (flow-core §2.1).
@@ -64,7 +64,8 @@ of truth, and an argument that disagrees with it is ignored and named in the log
64
64
  | `merged` | none, or nothing published | `blocked` — nothing of this ticket was published from here |
65
65
  | `review` | exists | `$flow-work-respond` — the threads come from `<cmd> events --json` |
66
66
  | `pipeline` | exists | `$flow-work-green` — the failed jobs come from `<cmd> events --json` |
67
- | `review` · `pipeline` | none | `blocked` — there is no work of this ticket to answer for |
67
+ | `conflict` | exists | `$flow-work-green` — the MR/PR conflicts with its base; which base, and where it stands, come from `<cmd> events --json` |
68
+ | `review` · `pipeline` · `conflict` | none | `blocked` — there is no work of this ticket to answer for |
68
69
 
69
70
  **The work's branch, on `start` and `study`.** The current branch is `meta.json.branch` → nothing to do. It is
70
71
  not — a study made on another machine arrives on the ticket's `base`, a run that died before its
@@ -16,7 +16,7 @@ Every `/flow:*` command assumes these rules. They are stated once, here, so a co
16
16
  carries what is specific to its phase. Read this once per session; a command that says "load
17
17
  `flow-core`" means this file.
18
18
 
19
- **This file belongs to flow `0.90.0`.** Compare it once, at the start of the session, against
19
+ **This file belongs to flow `0.91.0`.** Compare it once, at the start of the session, against
20
20
  `version` in `~/.claude/flow/.claude-plugin/plugin.json`. The two differing means the session
21
21
  is running a **mixture** — the commands from one copy of the plugin, these shared rules from another
22
22
  — which is exactly what happens when a branch or a release candidate is loaded over an installed
@@ -243,11 +243,12 @@ configuration; these orders are the whole interface, and nothing else about the
243
243
  assumed:
244
244
 
245
245
  ```
246
- <cmd> why → start | study | answer | review | pipeline | merged
246
+ <cmd> why → start | study | answer | review | pipeline | merged | conflict
247
247
  <cmd> ticket --json → {number, title, body, comments[{author, at, text}], base, kind}
248
248
  <cmd> answer → one option's exact text, or free text; exit 2 = no reply
249
249
  <cmd> events --json → {"comments":[{thread,kind,id,author,at,body,url,path?,line?}]}
250
250
  | {"sha":…, "failed":[{name,conclusion,url,log_tail}]}
251
+ | {"conflict":{"base":…, "base_sha":…}}
251
252
  <cmd> ask --question-file F --options-file F [--recommended N] [--free-text] [--gate NAME]
252
253
  <cmd> publish --title-file F --body-file F [--part N --of M]
253
254
  <cmd> blocked --reason-file F
@@ -307,7 +308,7 @@ run has.
307
308
  runs the study phases as any run does, and three rules make it stop where it should:
308
309
 
309
310
  - **The door to code.** The first step of `/flow:feat:build` and `/flow:bug:fix` pre-flight, in
310
- `unattended`, re-reads `<cmd> why`: `start`, `answer`, `merged`, `review` or `pipeline` → go on;
311
+ `unattended`, re-reads `<cmd> why`: `start`, `answer`, `merged`, `review`, `pipeline` or `conflict` → go on;
311
312
  `study` → the study ends here; anything else, or the order failing → `blocked`. Every path from a
312
313
  study to code crosses that door, an answered question that resumes straight into `build`
313
314
  included, so the phases before it carry no clause. The run kind is read there, never stored: the
@@ -350,6 +351,7 @@ person asking for changes, a ticket that already has code — is `/flow:work:run
350
351
  | The next MR/PR of a train (`ship` close) | record — not started: one MR/PR per unattended run |
351
352
  | `build` with no startable MR/PR (its `depends_on` not `merged` in `meta.json`) | blocked — the reason names what must merge; an unattended `build` never stacks a branch on another, and never creates a remote branch |
352
353
  | The parent of a stacked MR/PR merged — rebase and force-push | blocked — never force-push unattended |
354
+ | Integrating the base into the MR/PR's branch (`green`) | on `why = conflict`, record — `git merge origin/<base>` as the orchestrator left it, never rebase, each conflict resolved on its merits (`/flow:work:green` §5.C); on any other `why`, blocked — the orchestrator brings the base in |
353
355
  | Any offer about the work's own bookkeeping — a tracker issue, the first `KNOWLEDGE.md` or a knowledge save, a FLOW convention, an agent lesson or a saved specialist, the follow-up survey, carrying files over from the main checkout, a contract handoff, archiving the work | record — `Later`; nothing written outside the work folder |
354
356
  | A step the command cannot complete (a red suite it cannot fix, a tool missing, auth failing, the same check failing a second time) | blocked |
355
357
  | Anything `auto` already decides on its own (size, flow mechanics, WIP commits, the next command) | as `auto` |
@@ -41,19 +41,34 @@ Read `~/.claude/flow/CORE.gemini.md` first (shared rules: `FLOW.md` step 0, mode
41
41
  4. **Integrating the base branch** — any `git merge`/`git rebase` of `git.default_base` into the branch, and any history rewrite or force-push it implies (§5.C).
42
42
  5. **Green-washing — NEVER, in any mode:** no rerun of a failed check hoping it passes; never disable, skip, `@skip`/`xit`, loosen a threshold, or delete a test/lint rule to force green; never resolve a conflict by blindly taking one side (`--ours`/`--theirs`, `checkout --theirs`, discarding the base's changes) — resolve by understanding both sides.
43
43
 
44
- **In `unattended`** (flow-core §2.1) — launched by `/flow:work:run` on `why = pipeline` — this
45
- command asks nothing and never touches the forge. Gate 5 holds exactly as written; the others
46
- resolve this way:
44
+ **In `unattended`** (flow-core §2.1) — launched by `/flow:work:run` on `why = pipeline` or
45
+ `why = conflict` — this command never touches the forge. Gate 5 holds exactly as written; the
46
+ others resolve this way:
47
47
 
48
48
  - **§1–§2** — no MR/PR is resolved and no forge is read: the failures are `<cmd> events --json` →
49
49
  `{"sha", "failed": [{name, conclusion, url, log_tail}]}`, and `log_tail` is the evidence. The order
50
50
  failing → `blocked`; `failed` empty → `done`, the summary saying so. `sha` not `HEAD` → `blocked`:
51
51
  the result is about another commit, and fixing it here would be fixing a guess.
52
+ On `why = conflict` the events are `{"conflict": {"base", "base_sha"}}` instead: the MR/PR
53
+ conflicts with `base`, which the orchestrator left in the checkout as `origin/<base>` at
54
+ `base_sha`. That is the only blocker of the round — category C, nothing to triage. `origin/<base>`
55
+ missing or not at `base_sha` → `blocked`: the run would merge a base nobody named.
52
56
  - **§3** — triage as written, recorded in `09-ci.md`. **K** (flaky / infra) → `blocked` with the
53
57
  evidence: the run has no rerun order, and the orchestrator owns reruns and the red-round limit.
54
- **C** (conflict, behind base) and anything needing a rebase or force-push → `blocked`: the
55
- orchestrator brings the base in. A **human** blocker → `blocked`, naming who. **S** → fixed within
58
+ **C** (conflict, behind base) on `why = pipeline`, and anything needing a rebase or force-push →
59
+ `blocked`: the orchestrator brings the base in, and relaunches with `why = conflict` when it
60
+ conflicts. A **human** blocker → `blocked`, naming who. **S** → fixed within
56
61
  scope, otherwise `blocked` with the justification.
62
+ - **§5.C on `why = conflict`** — gate 4 is recorded (`unattended:integrate-base`), never asked:
63
+ the orchestrator launched the run for exactly this. No fetch: the base is `origin/<base>` as the
64
+ orchestrator left it, never `git.default_base` read from the config. Always `git merge
65
+ origin/<base>`, never a rebase. Each conflict is resolved on its merits as step 3 says; step 6's
66
+ "intent of either side unclear" → `git merge --abort`, then question `decision` when the two
67
+ sides want things that contradict each other (a product decision: which intent wins), `blocked`
68
+ otherwise. The base it merges goes into this round of `09-ci.md` before the merge starts; the
69
+ answer re-enters at §5.C, reads the base there, and merges again from `origin/<base>` — an
70
+ unfinished merge does not survive the run. Step 4's design change that is more than a tweak →
71
+ `blocked`. The merge commit, after the full local gate, is the round's commit.
57
72
  - **§5** — fixes and the local verification as written; a local gate it cannot get green →
58
73
  `blocked`. A fix adding behaviour gets its brief recorded, not asked; a fix that needs a schema
59
74
  change, a design invalidation that is more than a tweak, or a high-severity finding from the
@@ -32,7 +32,7 @@ of truth, and an argument that disagrees with it is ignored and named in the log
32
32
  other mode a person is the router (`/flow:next`).
33
33
  - `autonomy.orchestrator_cmd` empty → flow-core §2.1: no phase runs.
34
34
  - Run `<cmd> why`. It fails, or prints anything but `start`, `study`, `answer`, `review`,
35
- `pipeline` or `merged` → print what it returned and its stderr in the §3 header and end. No closing order: an
35
+ `pipeline`, `merged` or `conflict` → print what it returned and its stderr in the §3 header and end. No closing order: an
36
36
  orchestrator that cannot say why it launched the run cannot take one either.
37
37
  - Run `<cmd> ticket --json` and keep `number`, `title`, `base` and `kind` (`kind` absent or `null` → `feat`: the tracker could not tell, so flow decides). `kind` is re-read on every run; only a run that starts the work uses it — once the work exists, its folder says feat or bug.
38
38
  It fails or prints no `number` → `blocked` (flow-core §2.1).
@@ -60,7 +60,8 @@ of truth, and an argument that disagrees with it is ignored and named in the log
60
60
  | `merged` | none, or nothing published | `blocked` — nothing of this ticket was published from here |
61
61
  | `review` | exists | `/flow:work:respond` — the threads come from `<cmd> events --json` |
62
62
  | `pipeline` | exists | `/flow:work:green` — the failed jobs come from `<cmd> events --json` |
63
- | `review` · `pipeline` | none | `blocked` — there is no work of this ticket to answer for |
63
+ | `conflict` | exists | `/flow:work:green` — the MR/PR conflicts with its base; which base, and where it stands, come from `<cmd> events --json` |
64
+ | `review` · `pipeline` · `conflict` | none | `blocked` — there is no work of this ticket to answer for |
64
65
 
65
66
  **The work's branch, on `start` and `study`.** The current branch is `meta.json.branch` → nothing to do. It is
66
67
  not — a study made on another machine arrives on the ticket's `base`, a run that died before its
@@ -17,7 +17,7 @@ Every `/flow-*` command assumes these rules. They are stated once, here, so a co
17
17
  carries what is specific to its phase. Read this once per session; a command that says "load
18
18
  `flow-core`" means this file.
19
19
 
20
- **This file belongs to flow `0.90.0`.** Compare it once, at the start of the session, against
20
+ **This file belongs to flow `0.91.0`.** Compare it once, at the start of the session, against
21
21
  `version` in `~/.claude/flow/.claude-plugin/plugin.json`. The two differing means the session
22
22
  is running a **mixture** — the commands from one copy of the plugin, these shared rules from another
23
23
  — which is exactly what happens when a branch or a release candidate is loaded over an installed
@@ -244,11 +244,12 @@ configuration; these orders are the whole interface, and nothing else about the
244
244
  assumed:
245
245
 
246
246
  ```
247
- <cmd> why → start | study | answer | review | pipeline | merged
247
+ <cmd> why → start | study | answer | review | pipeline | merged | conflict
248
248
  <cmd> ticket --json → {number, title, body, comments[{author, at, text}], base, kind}
249
249
  <cmd> answer → one option's exact text, or free text; exit 2 = no reply
250
250
  <cmd> events --json → {"comments":[{thread,kind,id,author,at,body,url,path?,line?}]}
251
251
  | {"sha":…, "failed":[{name,conclusion,url,log_tail}]}
252
+ | {"conflict":{"base":…, "base_sha":…}}
252
253
  <cmd> ask --question-file F --options-file F [--recommended N] [--free-text] [--gate NAME]
253
254
  <cmd> publish --title-file F --body-file F [--part N --of M]
254
255
  <cmd> blocked --reason-file F
@@ -308,7 +309,7 @@ run has.
308
309
  runs the study phases as any run does, and three rules make it stop where it should:
309
310
 
310
311
  - **The door to code.** The first step of `/flow-feat-build` and `/flow-bug-fix` pre-flight, in
311
- `unattended`, re-reads `<cmd> why`: `start`, `answer`, `merged`, `review` or `pipeline` → go on;
312
+ `unattended`, re-reads `<cmd> why`: `start`, `answer`, `merged`, `review`, `pipeline` or `conflict` → go on;
312
313
  `study` → the study ends here; anything else, or the order failing → `blocked`. Every path from a
313
314
  study to code crosses that door, an answered question that resumes straight into `build`
314
315
  included, so the phases before it carry no clause. The run kind is read there, never stored: the
@@ -351,6 +352,7 @@ person asking for changes, a ticket that already has code — is `/flow-work-run
351
352
  | The next MR/PR of a train (`ship` close) | record — not started: one MR/PR per unattended run |
352
353
  | `build` with no startable MR/PR (its `depends_on` not `merged` in `meta.json`) | blocked — the reason names what must merge; an unattended `build` never stacks a branch on another, and never creates a remote branch |
353
354
  | The parent of a stacked MR/PR merged — rebase and force-push | blocked — never force-push unattended |
355
+ | Integrating the base into the MR/PR's branch (`green`) | on `why = conflict`, record — `git merge origin/<base>` as the orchestrator left it, never rebase, each conflict resolved on its merits (`/flow-work-green` §5.C); on any other `why`, blocked — the orchestrator brings the base in |
354
356
  | Any offer about the work's own bookkeeping — a tracker issue, the first `KNOWLEDGE.md` or a knowledge save, a FLOW convention, an agent lesson or a saved specialist, the follow-up survey, carrying files over from the main checkout, a contract handoff, archiving the work | record — `Later`; nothing written outside the work folder |
355
357
  | A step the command cannot complete (a red suite it cannot fix, a tool missing, auth failing, the same check failing a second time) | blocked |
356
358
  | Anything `auto` already decides on its own (size, flow mechanics, WIP commits, the next command) | as `auto` |
@@ -45,19 +45,34 @@ Read `~/.claude/flow/CORE.hermes.md` first (shared rules: `FLOW.md` step 0, mode
45
45
  4. **Integrating the base branch** — any `git merge`/`git rebase` of `git.default_base` into the branch, and any history rewrite or force-push it implies (§5.C).
46
46
  5. **Green-washing — NEVER, in any mode:** no rerun of a failed check hoping it passes; never disable, skip, `@skip`/`xit`, loosen a threshold, or delete a test/lint rule to force green; never resolve a conflict by blindly taking one side (`--ours`/`--theirs`, `checkout --theirs`, discarding the base's changes) — resolve by understanding both sides.
47
47
 
48
- **In `unattended`** (flow-core §2.1) — launched by `/flow-work-run` on `why = pipeline` — this
49
- command asks nothing and never touches the forge. Gate 5 holds exactly as written; the others
50
- resolve this way:
48
+ **In `unattended`** (flow-core §2.1) — launched by `/flow-work-run` on `why = pipeline` or
49
+ `why = conflict` — this command never touches the forge. Gate 5 holds exactly as written; the
50
+ others resolve this way:
51
51
 
52
52
  - **§1–§2** — no MR/PR is resolved and no forge is read: the failures are `<cmd> events --json` →
53
53
  `{"sha", "failed": [{name, conclusion, url, log_tail}]}`, and `log_tail` is the evidence. The order
54
54
  failing → `blocked`; `failed` empty → `done`, the summary saying so. `sha` not `HEAD` → `blocked`:
55
55
  the result is about another commit, and fixing it here would be fixing a guess.
56
+ On `why = conflict` the events are `{"conflict": {"base", "base_sha"}}` instead: the MR/PR
57
+ conflicts with `base`, which the orchestrator left in the checkout as `origin/<base>` at
58
+ `base_sha`. That is the only blocker of the round — category C, nothing to triage. `origin/<base>`
59
+ missing or not at `base_sha` → `blocked`: the run would merge a base nobody named.
56
60
  - **§3** — triage as written, recorded in `09-ci.md`. **K** (flaky / infra) → `blocked` with the
57
61
  evidence: the run has no rerun order, and the orchestrator owns reruns and the red-round limit.
58
- **C** (conflict, behind base) and anything needing a rebase or force-push → `blocked`: the
59
- orchestrator brings the base in. A **human** blocker → `blocked`, naming who. **S** → fixed within
62
+ **C** (conflict, behind base) on `why = pipeline`, and anything needing a rebase or force-push →
63
+ `blocked`: the orchestrator brings the base in, and relaunches with `why = conflict` when it
64
+ conflicts. A **human** blocker → `blocked`, naming who. **S** → fixed within
60
65
  scope, otherwise `blocked` with the justification.
66
+ - **§5.C on `why = conflict`** — gate 4 is recorded (`unattended:integrate-base`), never asked:
67
+ the orchestrator launched the run for exactly this. No fetch: the base is `origin/<base>` as the
68
+ orchestrator left it, never `git.default_base` read from the config. Always `git merge
69
+ origin/<base>`, never a rebase. Each conflict is resolved on its merits as step 3 says; step 6's
70
+ "intent of either side unclear" → `git merge --abort`, then question `decision` when the two
71
+ sides want things that contradict each other (a product decision: which intent wins), `blocked`
72
+ otherwise. The base it merges goes into this round of `09-ci.md` before the merge starts; the
73
+ answer re-enters at §5.C, reads the base there, and merges again from `origin/<base>` — an
74
+ unfinished merge does not survive the run. Step 4's design change that is more than a tweak →
75
+ `blocked`. The merge commit, after the full local gate, is the round's commit.
61
76
  - **§5** — fixes and the local verification as written; a local gate it cannot get green →
62
77
  `blocked`. A fix adding behaviour gets its brief recorded, not asked; a fix that needs a schema
63
78
  change, a design invalidation that is more than a tweak, or a high-severity finding from the
@@ -36,7 +36,7 @@ of truth, and an argument that disagrees with it is ignored and named in the log
36
36
  other mode a person is the router (`/flow-next`).
37
37
  - `autonomy.orchestrator_cmd` empty → flow-core §2.1: no phase runs.
38
38
  - Run `<cmd> why`. It fails, or prints anything but `start`, `study`, `answer`, `review`,
39
- `pipeline` or `merged` → print what it returned and its stderr in the §3 header and end. No closing order: an
39
+ `pipeline`, `merged` or `conflict` → print what it returned and its stderr in the §3 header and end. No closing order: an
40
40
  orchestrator that cannot say why it launched the run cannot take one either.
41
41
  - Run `<cmd> ticket --json` and keep `number`, `title`, `base` and `kind` (`kind` absent or `null` → `feat`: the tracker could not tell, so flow decides). `kind` is re-read on every run; only a run that starts the work uses it — once the work exists, its folder says feat or bug.
42
42
  It fails or prints no `number` → `blocked` (flow-core §2.1).
@@ -64,7 +64,8 @@ of truth, and an argument that disagrees with it is ignored and named in the log
64
64
  | `merged` | none, or nothing published | `blocked` — nothing of this ticket was published from here |
65
65
  | `review` | exists | `/flow-work-respond` — the threads come from `<cmd> events --json` |
66
66
  | `pipeline` | exists | `/flow-work-green` — the failed jobs come from `<cmd> events --json` |
67
- | `review` · `pipeline` | none | `blocked` — there is no work of this ticket to answer for |
67
+ | `conflict` | exists | `/flow-work-green` — the MR/PR conflicts with its base; which base, and where it stands, come from `<cmd> events --json` |
68
+ | `review` · `pipeline` · `conflict` | none | `blocked` — there is no work of this ticket to answer for |
68
69
 
69
70
  **The work's branch, on `start` and `study`.** The current branch is `meta.json.branch` → nothing to do. It is
70
71
  not — a study made on another machine arrives on the ticket's `base`, a run that died before its
@@ -16,7 +16,7 @@ Every `/flow-*` command assumes these rules. They are stated once, here, so a co
16
16
  carries what is specific to its phase. Read this once per session; a command that says "load
17
17
  `flow-core`" means this file.
18
18
 
19
- **This file belongs to flow `0.90.0`.** Compare it once, at the start of the session, against
19
+ **This file belongs to flow `0.91.0`.** Compare it once, at the start of the session, against
20
20
  `version` in `~/.claude/flow/.claude-plugin/plugin.json`. The two differing means the session
21
21
  is running a **mixture** — the commands from one copy of the plugin, these shared rules from another
22
22
  — which is exactly what happens when a branch or a release candidate is loaded over an installed
@@ -243,11 +243,12 @@ configuration; these orders are the whole interface, and nothing else about the
243
243
  assumed:
244
244
 
245
245
  ```
246
- <cmd> why → start | study | answer | review | pipeline | merged
246
+ <cmd> why → start | study | answer | review | pipeline | merged | conflict
247
247
  <cmd> ticket --json → {number, title, body, comments[{author, at, text}], base, kind}
248
248
  <cmd> answer → one option's exact text, or free text; exit 2 = no reply
249
249
  <cmd> events --json → {"comments":[{thread,kind,id,author,at,body,url,path?,line?}]}
250
250
  | {"sha":…, "failed":[{name,conclusion,url,log_tail}]}
251
+ | {"conflict":{"base":…, "base_sha":…}}
251
252
  <cmd> ask --question-file F --options-file F [--recommended N] [--free-text] [--gate NAME]
252
253
  <cmd> publish --title-file F --body-file F [--part N --of M]
253
254
  <cmd> blocked --reason-file F
@@ -307,7 +308,7 @@ run has.
307
308
  runs the study phases as any run does, and three rules make it stop where it should:
308
309
 
309
310
  - **The door to code.** The first step of `/flow-feat-build` and `/flow-bug-fix` pre-flight, in
310
- `unattended`, re-reads `<cmd> why`: `start`, `answer`, `merged`, `review` or `pipeline` → go on;
311
+ `unattended`, re-reads `<cmd> why`: `start`, `answer`, `merged`, `review`, `pipeline` or `conflict` → go on;
311
312
  `study` → the study ends here; anything else, or the order failing → `blocked`. Every path from a
312
313
  study to code crosses that door, an answered question that resumes straight into `build`
313
314
  included, so the phases before it carry no clause. The run kind is read there, never stored: the
@@ -350,6 +351,7 @@ person asking for changes, a ticket that already has code — is `/flow-work-run
350
351
  | The next MR/PR of a train (`ship` close) | record — not started: one MR/PR per unattended run |
351
352
  | `build` with no startable MR/PR (its `depends_on` not `merged` in `meta.json`) | blocked — the reason names what must merge; an unattended `build` never stacks a branch on another, and never creates a remote branch |
352
353
  | The parent of a stacked MR/PR merged — rebase and force-push | blocked — never force-push unattended |
354
+ | Integrating the base into the MR/PR's branch (`green`) | on `why = conflict`, record — `git merge origin/<base>` as the orchestrator left it, never rebase, each conflict resolved on its merits (`/flow-work-green` §5.C); on any other `why`, blocked — the orchestrator brings the base in |
353
355
  | Any offer about the work's own bookkeeping — a tracker issue, the first `KNOWLEDGE.md` or a knowledge save, a FLOW convention, an agent lesson or a saved specialist, the follow-up survey, carrying files over from the main checkout, a contract handoff, archiving the work | record — `Later`; nothing written outside the work folder |
354
356
  | A step the command cannot complete (a red suite it cannot fix, a tool missing, auth failing, the same check failing a second time) | blocked |
355
357
  | Anything `auto` already decides on its own (size, flow mechanics, WIP commits, the next command) | as `auto` |
@@ -43,19 +43,34 @@ Read `~/.claude/flow/CORE.opencode.md` first (shared rules: `FLOW.md` step 0, mo
43
43
  4. **Integrating the base branch** — any `git merge`/`git rebase` of `git.default_base` into the branch, and any history rewrite or force-push it implies (§5.C).
44
44
  5. **Green-washing — NEVER, in any mode:** no rerun of a failed check hoping it passes; never disable, skip, `@skip`/`xit`, loosen a threshold, or delete a test/lint rule to force green; never resolve a conflict by blindly taking one side (`--ours`/`--theirs`, `checkout --theirs`, discarding the base's changes) — resolve by understanding both sides.
45
45
 
46
- **In `unattended`** (flow-core §2.1) — launched by `/flow-work-run` on `why = pipeline` — this
47
- command asks nothing and never touches the forge. Gate 5 holds exactly as written; the others
48
- resolve this way:
46
+ **In `unattended`** (flow-core §2.1) — launched by `/flow-work-run` on `why = pipeline` or
47
+ `why = conflict` — this command never touches the forge. Gate 5 holds exactly as written; the
48
+ others resolve this way:
49
49
 
50
50
  - **§1–§2** — no MR/PR is resolved and no forge is read: the failures are `<cmd> events --json` →
51
51
  `{"sha", "failed": [{name, conclusion, url, log_tail}]}`, and `log_tail` is the evidence. The order
52
52
  failing → `blocked`; `failed` empty → `done`, the summary saying so. `sha` not `HEAD` → `blocked`:
53
53
  the result is about another commit, and fixing it here would be fixing a guess.
54
+ On `why = conflict` the events are `{"conflict": {"base", "base_sha"}}` instead: the MR/PR
55
+ conflicts with `base`, which the orchestrator left in the checkout as `origin/<base>` at
56
+ `base_sha`. That is the only blocker of the round — category C, nothing to triage. `origin/<base>`
57
+ missing or not at `base_sha` → `blocked`: the run would merge a base nobody named.
54
58
  - **§3** — triage as written, recorded in `09-ci.md`. **K** (flaky / infra) → `blocked` with the
55
59
  evidence: the run has no rerun order, and the orchestrator owns reruns and the red-round limit.
56
- **C** (conflict, behind base) and anything needing a rebase or force-push → `blocked`: the
57
- orchestrator brings the base in. A **human** blocker → `blocked`, naming who. **S** → fixed within
60
+ **C** (conflict, behind base) on `why = pipeline`, and anything needing a rebase or force-push →
61
+ `blocked`: the orchestrator brings the base in, and relaunches with `why = conflict` when it
62
+ conflicts. A **human** blocker → `blocked`, naming who. **S** → fixed within
58
63
  scope, otherwise `blocked` with the justification.
64
+ - **§5.C on `why = conflict`** — gate 4 is recorded (`unattended:integrate-base`), never asked:
65
+ the orchestrator launched the run for exactly this. No fetch: the base is `origin/<base>` as the
66
+ orchestrator left it, never `git.default_base` read from the config. Always `git merge
67
+ origin/<base>`, never a rebase. Each conflict is resolved on its merits as step 3 says; step 6's
68
+ "intent of either side unclear" → `git merge --abort`, then question `decision` when the two
69
+ sides want things that contradict each other (a product decision: which intent wins), `blocked`
70
+ otherwise. The base it merges goes into this round of `09-ci.md` before the merge starts; the
71
+ answer re-enters at §5.C, reads the base there, and merges again from `origin/<base>` — an
72
+ unfinished merge does not survive the run. Step 4's design change that is more than a tweak →
73
+ `blocked`. The merge commit, after the full local gate, is the round's commit.
59
74
  - **§5** — fixes and the local verification as written; a local gate it cannot get green →
60
75
  `blocked`. A fix adding behaviour gets its brief recorded, not asked; a fix that needs a schema
61
76
  change, a design invalidation that is more than a tweak, or a high-severity finding from the
@@ -34,7 +34,7 @@ of truth, and an argument that disagrees with it is ignored and named in the log
34
34
  other mode a person is the router (`/flow-next`).
35
35
  - `autonomy.orchestrator_cmd` empty → flow-core §2.1: no phase runs.
36
36
  - Run `<cmd> why`. It fails, or prints anything but `start`, `study`, `answer`, `review`,
37
- `pipeline` or `merged` → print what it returned and its stderr in the §3 header and end. No closing order: an
37
+ `pipeline`, `merged` or `conflict` → print what it returned and its stderr in the §3 header and end. No closing order: an
38
38
  orchestrator that cannot say why it launched the run cannot take one either.
39
39
  - Run `<cmd> ticket --json` and keep `number`, `title`, `base` and `kind` (`kind` absent or `null` → `feat`: the tracker could not tell, so flow decides). `kind` is re-read on every run; only a run that starts the work uses it — once the work exists, its folder says feat or bug.
40
40
  It fails or prints no `number` → `blocked` (flow-core §2.1).
@@ -62,7 +62,8 @@ of truth, and an argument that disagrees with it is ignored and named in the log
62
62
  | `merged` | none, or nothing published | `blocked` — nothing of this ticket was published from here |
63
63
  | `review` | exists | `/flow-work-respond` — the threads come from `<cmd> events --json` |
64
64
  | `pipeline` | exists | `/flow-work-green` — the failed jobs come from `<cmd> events --json` |
65
- | `review` · `pipeline` | none | `blocked` — there is no work of this ticket to answer for |
65
+ | `conflict` | exists | `/flow-work-green` — the MR/PR conflicts with its base; which base, and where it stands, come from `<cmd> events --json` |
66
+ | `review` · `pipeline` · `conflict` | none | `blocked` — there is no work of this ticket to answer for |
66
67
 
67
68
  **The work's branch, on `start` and `study`.** The current branch is `meta.json.branch` → nothing to do. It is
68
69
  not — a study made on another machine arrives on the ticket's `base`, a run that died before its
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flow-workflows",
3
- "version": "0.90.0",
3
+ "version": "0.91.0",
4
4
  "description": "Guided feat/bug workflows (start→ship), post-deploy monitoring and multi-agent code review, stack-agnostic. Each repo uses a shared FLOW.md plus optional harness overlay.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -3,7 +3,7 @@
3
3
  "name": "flow",
4
4
  "displayName": "Flow — guided dev workflows",
5
5
  "description": "Guided feat/bug workflows (start→ship), post-deploy monitoring and multi-agent code review, stack-agnostic. Each repo uses a shared FLOW.md plus optional harness overlay.",
6
- "version": "0.90.0",
6
+ "version": "0.91.0",
7
7
  "author": {
8
8
  "name": "Alberto Vioque",
9
9
  "email": "mashware@gmail.com"
@@ -5,6 +5,22 @@ plugin and is what `/flow:news` reads to show you what changed since your previo
5
5
 
6
6
  The canonical, richest notes live in the [GitHub Releases](https://github.com/mashware/flow-workflows/releases).
7
7
 
8
+ ## v0.91.0 — An unattended run resolves the conflicts with its base when the orchestrator launches it for them · 2026-10-11
9
+
10
+ **In short**
11
+ - **A new `why`: `conflict`.** An orchestrator that sees the run's open MR/PR conflict with its base
12
+ launches it with `why = conflict`; `/flow:work:run` sends it to `/flow:work:green`. Before, an
13
+ unattended `green` turned any conflict into `blocked` and the draft waited for a person.
14
+ - **`<cmd> events --json`** on such a run is `{"conflict": {"base", "base_sha"}}`, and the base is in
15
+ the checkout as `origin/<base>` at that commit — the orchestrator brings it in, the run never
16
+ fetches.
17
+ - **`green` merges, never rebases**, and resolves each conflict on its merits, exactly as §5.C
18
+ already says (no `--ours`/`--theirs` wholesale, generated files regenerated, the full local gate
19
+ after), then publishes. Integrating the base is recorded, not asked: the run was launched for it.
20
+ - **Two sides that want contradicting things are a product decision**: the merge is aborted and the
21
+ run asks (`decision`). The answer re-enters `green`, which merges again from `origin/<base>`.
22
+ - On any other `why`, a conflict is still `blocked`.
23
+
8
24
  ## v0.90.0 — A query that changed reaches the MR with its plan, or with the admission that nobody measured it · 2026-10-07
9
25
 
10
26
  **In short**