flow-workflows 0.92.0 → 0.94.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.
Files changed (70) hide show
  1. package/README.md +4 -4
  2. package/adapters/codex/CORE.md +61 -20
  3. package/adapters/codex/skills/flow-bug-fix/SKILL.md +9 -1
  4. package/adapters/codex/skills/flow-bug-investigate/SKILL.md +11 -0
  5. package/adapters/codex/skills/flow-bug-validate/SKILL.md +1 -1
  6. package/adapters/codex/skills/flow-doctor/SKILL.md +33 -15
  7. package/adapters/codex/skills/flow-feat-build/SKILL.md +9 -2
  8. package/adapters/codex/skills/flow-feat-design/SKILL.md +32 -2
  9. package/adapters/codex/skills/flow-feat-plan/SKILL.md +1 -0
  10. package/adapters/codex/skills/flow-feat-ship/SKILL.md +3 -1
  11. package/adapters/codex/skills/flow-feat-start/SKILL.md +1 -1
  12. package/adapters/codex/skills/flow-feat-validate/SKILL.md +1 -1
  13. package/adapters/codex/skills/flow-init/SKILL.md +12 -8
  14. package/adapters/codex/skills/flow-next/SKILL.md +5 -4
  15. package/adapters/codex/skills/flow-work-README/SKILL.md +9 -2
  16. package/adapters/codex/skills/flow-work-handoff/SKILL.md +19 -5
  17. package/adapters/codex/skills/flow-work-run/SKILL.md +18 -2
  18. package/adapters/gemini/CORE.md +61 -20
  19. package/adapters/gemini/commands/flow/bug/fix.toml +9 -1
  20. package/adapters/gemini/commands/flow/bug/investigate.toml +11 -0
  21. package/adapters/gemini/commands/flow/bug/validate.toml +1 -1
  22. package/adapters/gemini/commands/flow/doctor.toml +33 -15
  23. package/adapters/gemini/commands/flow/feat/build.toml +9 -2
  24. package/adapters/gemini/commands/flow/feat/design.toml +32 -2
  25. package/adapters/gemini/commands/flow/feat/plan.toml +1 -0
  26. package/adapters/gemini/commands/flow/feat/ship.toml +3 -1
  27. package/adapters/gemini/commands/flow/feat/start.toml +1 -1
  28. package/adapters/gemini/commands/flow/feat/validate.toml +1 -1
  29. package/adapters/gemini/commands/flow/init.toml +12 -8
  30. package/adapters/gemini/commands/flow/next.toml +5 -4
  31. package/adapters/gemini/commands/flow/work/README.toml +9 -2
  32. package/adapters/gemini/commands/flow/work/handoff.toml +19 -5
  33. package/adapters/gemini/commands/flow/work/run.toml +18 -2
  34. package/adapters/hermes/CORE.md +61 -20
  35. package/adapters/hermes/skills/flow-bug-fix/SKILL.md +9 -1
  36. package/adapters/hermes/skills/flow-bug-investigate/SKILL.md +11 -0
  37. package/adapters/hermes/skills/flow-bug-validate/SKILL.md +1 -1
  38. package/adapters/hermes/skills/flow-doctor/SKILL.md +33 -15
  39. package/adapters/hermes/skills/flow-feat-build/SKILL.md +9 -2
  40. package/adapters/hermes/skills/flow-feat-design/SKILL.md +32 -2
  41. package/adapters/hermes/skills/flow-feat-plan/SKILL.md +1 -0
  42. package/adapters/hermes/skills/flow-feat-ship/SKILL.md +3 -1
  43. package/adapters/hermes/skills/flow-feat-start/SKILL.md +1 -1
  44. package/adapters/hermes/skills/flow-feat-validate/SKILL.md +1 -1
  45. package/adapters/hermes/skills/flow-init/SKILL.md +12 -8
  46. package/adapters/hermes/skills/flow-next/SKILL.md +5 -4
  47. package/adapters/hermes/skills/flow-work-README/SKILL.md +9 -2
  48. package/adapters/hermes/skills/flow-work-handoff/SKILL.md +19 -5
  49. package/adapters/hermes/skills/flow-work-run/SKILL.md +18 -2
  50. package/adapters/opencode/CORE.md +61 -20
  51. package/adapters/opencode/commands/flow-bug-fix.md +9 -1
  52. package/adapters/opencode/commands/flow-bug-investigate.md +11 -0
  53. package/adapters/opencode/commands/flow-bug-validate.md +1 -1
  54. package/adapters/opencode/commands/flow-doctor.md +33 -15
  55. package/adapters/opencode/commands/flow-feat-build.md +9 -2
  56. package/adapters/opencode/commands/flow-feat-design.md +32 -2
  57. package/adapters/opencode/commands/flow-feat-plan.md +1 -0
  58. package/adapters/opencode/commands/flow-feat-ship.md +3 -1
  59. package/adapters/opencode/commands/flow-feat-start.md +1 -1
  60. package/adapters/opencode/commands/flow-feat-validate.md +1 -1
  61. package/adapters/opencode/commands/flow-init.md +12 -8
  62. package/adapters/opencode/commands/flow-next.md +5 -4
  63. package/adapters/opencode/commands/flow-work-README.md +9 -2
  64. package/adapters/opencode/commands/flow-work-handoff.md +19 -5
  65. package/adapters/opencode/commands/flow-work-run.md +18 -2
  66. package/bin/cli.mjs +160 -65
  67. package/package.json +1 -1
  68. package/plugins/flow/.claude-plugin/plugin.json +1 -1
  69. package/plugins/flow/CHANGELOG.md +61 -0
  70. package/plugins/flow/examples/FLOW.template.md +13 -4
@@ -101,8 +101,8 @@ authorization, payments, personal data, a public contract, a migration):
101
101
  Each advisor gets this brief, with its lens substituted:
102
102
 
103
103
  > Propose ONE approach to solve ticket `<TICKET>`, from this lens: `<lens brief>`. Read
104
- > `.claude/work/<TICKET>/01-context.md` for context and the effective FLOW configuration (base plus
105
- > active harness overlay) for project conventions. What already exists in the repository:
104
+ > `.claude/work/<TICKET>/01-context.md` for context and the effective FLOW configuration (base, the
105
+ > context layer `FLOW_CONTEXT` selects, and the active harness overlay) for project conventions. What already exists in the repository:
106
106
  > `<the §1.5.1 inventory>` — propose a new piece only where nothing there fits. Do not
107
107
  > write code. Be specific about real modules and layers of this project. Report: name, what it is
108
108
  > (one sentence), modules/layers affected, main risk, and why it could be a bad idea. Under 250 words.
@@ -288,6 +288,9 @@ Consolidate outputs into `.claude/work/<TICKET>/03-design.md`:
288
288
  - **Invariant**: <e.g. "after assignTo(user), ticket.assignee == user AND ticket.status != 'unassigned'">
289
289
  - **Edge / boundary**: <e.g. "empty input list → returns 0, does not throw">
290
290
 
291
+ ## Depends on other tickets
292
+ <§5.1: one line per ticket this design cannot be built without — `- <ticket> — <what it brings that the base branch lacks>` — then, under "Not dependencies (either order works)", each premise on another ticket that holds whichever merges first, with one line why. Neither → "none".>
293
+
291
294
  ## Defensive mechanisms and their justification
292
295
  <One row per validation, guard, retry, lock, fallback, cache, idempotency, queue, or flag the design introduces. If you cannot name a REAL and PRESENT scenario that justifies it, the piece is unnecessary — remove it from the design.>
293
296
 
@@ -316,6 +319,33 @@ Consolidate outputs into `.claude/work/<TICKET>/03-design.md`:
316
319
 
317
320
  **"Acceptance criteria"**: start from the provisional list in `01-context.md` (pinned from the ticket in `/flow-feat-start`), fold in the clarifications and the internal/external contracts decided here, and promote it to the canonical enumerated list `/flow-feat-validate` gates against — observable, verifiable, proportional to size.
318
321
 
322
+ ### 5.1 Tickets this design depends on
323
+
324
+ Fill `## Depends on other tickets` now, before the challenger of §6 reads the design. The study is
325
+ often built by someone who never saw it made — another person, an unattended server — and who
326
+ starts from the base. A design that rests on what another ticket has not delivered yet leaves that
327
+ builder to find the piece missing and either ask or redo it.
328
+
329
+ - **A dependency** is a piece, contract or decision the chosen design needs, that is **not on the
330
+ base this work builds from** (`meta.json.base`, empty → `git.default_base`) — checked there, after
331
+ a best-effort `git fetch origin <base>`, never assumed from a local ref — and that **another
332
+ ticket** of this tracker brings. Missing from the base with no ticket bringing it → it is scope
333
+ or an open question, not a dependency. A ticket in another repo is not a `ticket_deps` entry —
334
+ the orchestrator only resolves this tracker's numbers — so write it in the section as a
335
+ cross-repo dependency, for a person, and leave it out of the list.
336
+ - **Not a dependency**: a premise that holds whichever ticket merges first. Say so under "Not
337
+ dependencies (either order works)", so nobody waits for it.
338
+ - **Record each one** in that section and in `meta.json.ticket_deps` —
339
+ `{ "ticket": "<the reference as a ticket body writes it: #253, MT-123>", "why": "<one line>" }`,
340
+ never one twice. `ticket_deps` is the record the exits read (`/flow-work-handoff` §5, the door to
341
+ code of an unattended study run, flow-core §2.1); the section is the study's prose. Each run of
342
+ this phase writes the list whole from the design it closes; `plan`, which runs after it, appends
343
+ its own again. A §6 response or a §9 edit that changes what the design needs changes
344
+ the section and the list together. None → `[]` and "none".
345
+
346
+ `ticket_deps` is not `mrs[].depends_on`: that one orders this work's own MRs/PRs, this one names
347
+ other tickets. Flow never checks whether a dependency has closed — whoever builds waits for it.
348
+
319
349
  ## 6. Design challenge (challenger)
320
350
 
321
351
  Before closing, **challenge the design** with an `Agent general-purpose` and this self-contained brief:
@@ -124,6 +124,7 @@ Add the `mrs` array with the agreed plan:
124
124
  ```
125
125
 
126
126
  - `n` = execution order (topological): `depends_on` only ever references a **lower** `n`; `wave` groups MRs/PRs that can run in parallel. `/flow-feat-build §1` reads `depends_on` to pick the next **startable** MR/PR and to say which can go in parallel — keep both accurate whenever the plan is edited or renumbered.
127
+ - **Another ticket is not a `depends_on`.** An MR/PR that turns out, while splitting, to need something another ticket brings is a dependency of the study: append it to `meta.json.ticket_deps` as `/flow-feat-design` §5.1 says, name it in that MR/PR's entry of `04-mr-plan.md` beside what it waits on, and leave `03-design.md` as it closed. The design's own entries stand as they are.
127
128
  - **`phases_done`** starts `[]` in every seeded entry: it tracks `build`/`review`/`validate` **for that MR/PR specifically**, so the gates in `/flow-feat-review §1`, `/flow-feat-validate §1` and `/flow-feat-ship §1` judge *this* MR/PR — a sibling's review never satisfies a new MR/PR's gate.
128
129
  - Estimates are **indicative**, not contractual. `/flow-feat-build` uses them as a thermometer: real work over `lines_est` +50% or `files_est + 2` triggers the "cut or continue" question (see §2.3 in build). **A thermometer is not a target** (flow-core §9): an estimate is never met by deleting comments, tests or blank lines, by compressing readable code, or by cutting where the piece is not coherent — the overrun is recorded instead, and a diff shaped to fit a number is the one case where these estimates lie to the phases downstream.
129
130
 
@@ -531,7 +531,9 @@ Read `meta.json.conventions_candidates[]` (flow-core §8). **No entries with `st
531
531
  decision — the FLOW config is personal — so it is one question, never a negotiation.
532
532
  4. **Add / Replace** → append a `conventions` line to the base `FLOW.md`. For a `quality.<key>`,
533
533
  update the file its effective value came from, or the base when it was absent; otherwise an
534
- overlay would immediately hide the correction. Show the old value and source in the result.
534
+ overlay would immediately hide the correction. A value from the context layer (flow-core §0) is
535
+ not edited here: that file is committed and the MR/PR is already out, so record the candidate as
536
+ a `followups[]` entry (`kind: "tooling"`) naming the file and the line instead. Show the old value and source in the result.
535
537
  Then `status: "added"`. **Not a rule** → `declined`, never offered again in any work.
536
538
  **Later** → stays `proposed` and is offered again by the next `ship` of a work that has it.
537
539
  5. **One line on screen**: how many rules were added and where, never a list of the texts —
@@ -48,7 +48,7 @@ its reason file in a `mktemp -d` directory (flow-core §2.1).
48
48
 
49
49
  ## 1. Pre-flight
50
50
 
51
- - Read the effective FLOW configuration per flow-core §0; neither base nor active overlay → each
51
+ - Read the effective FLOW configuration per flow-core §0; no FLOW layer present → each
52
52
  step's default. This command **creates** `00-summary.md` (§6) instead of reading it (flow-core §5).
53
53
  - No recognizable project structure → warn and stop.
54
54
  - **Determine the mode**: `$ARGUMENTS` non-empty → *ticket mode* (identifier = `$ARGUMENTS`); empty → *ticket-less* (identifier = the §2.5 slug).
@@ -36,7 +36,7 @@ One of the three below writes and two of them read, so they do not all go at onc
36
36
 
37
37
  **First, alone — the writer.** It is told the **test files are the deliverable**, saved as each one is finished, not at the end:
38
38
 
39
- 1. **Testing agent**: the `agents.testing` agent from the effective FLOW config; if empty, `Agent general-purpose` with this role. Brief: "Review the branch changes and complete the test suite where coverage is missing. Focus: the acceptance criteria in `03-design.md` marked `test` that no current test demonstrably asserts (see the §3 mapping), plus edge cases from `03-design.md`, error paths, input validations, emitted domain events. Do not rewrite tests that already pass. Read `.claude/work/<TICKET>/03-design.md` and `05-implementation.md`. Follow the project's effective test conventions from `FLOW.md` plus the active harness overlay."
39
+ 1. **Testing agent**: the `agents.testing` agent from the effective FLOW config; if empty, `Agent general-purpose` with this role. Brief: "Review the branch changes and complete the test suite where coverage is missing. Focus: the acceptance criteria in `03-design.md` marked `test` that no current test demonstrably asserts (see the §3 mapping), plus edge cases from `03-design.md`, error paths, input validations, emitted domain events. Do not rewrite tests that already pass. Read `.claude/work/<TICKET>/03-design.md` and `05-implementation.md`. Follow the project's effective test conventions from `FLOW.md`, the context layer `FLOW_CONTEXT` selects and the active harness overlay."
40
40
 
41
41
  **Then, in parallel — the readers**, once the testing agent has reported and its files are on disk. The suite runs here and not earlier for a second reason beyond the collision: run after the writer, it is the first thing that has ever executed the tests this phase just added.
42
42
 
@@ -22,14 +22,17 @@ and optional harness-owned values in the active `FLOW.<harness>.md`. The active
22
22
  `FLOW.zcode.md`; identify it from the
23
23
  product executing this command, never from the selected model (zcode runs the Claude pages too, so
24
24
  the page you are reading does not name the harness). Every other `/flow-*` command reads
25
- the base and then that overlay. The user answers the **minimum**: what the repo can tell is
25
+ the base, then the context layer `FLOW_CONTEXT` selects (flow-core §0), then that overlay. A
26
+ context file is the repo's, committed for where flow runs: `init` writes neither it nor its key. The user answers the **minimum**: what the repo can tell is
26
27
  auto-detected and only confirmed.
27
28
 
28
29
  Key names and contract: `examples/FLOW.template.md` from the plugin. Do not invent keys that are not there.
29
30
 
30
31
  ## 1. If either configuration file already exists
31
32
 
32
- Show `FLOW.md` and the active overlay when each exists, then show their effective merged values.
33
+ Show `FLOW.md` and the active overlay when each exists, then show their effective merged values —
34
+ with the context layer `FLOW_CONTEXT` selects merged in and named when it is set (flow-core §0), so
35
+ a value it masks is not offered as if the base still decided it.
33
36
  Ask: **update** (re-detect and re-ask, preserving what the user keeps) or **cancel**. Never read,
34
37
  change, or display another harness's overlay. Never overwrite either file without confirmation.
35
38
  Label harness-sensitive values that currently come from the base as **shared across harnesses**;
@@ -104,7 +107,7 @@ review, not a questionnaire. Then, and only then, five questions:
104
107
  4. **The quality commands as one block** (`quality.test`, `test_one`, `static_analysis`, `style_fix`,
105
108
  `db_update`, `db_diff`) — confirm or edit what §2 found, all in one question, each may stay empty
106
109
  (= auto-discover at the moment it is needed). Several suites chain into `test` with `&&`.
107
- 5. **Git-ignore** `FLOW.md`, `FLOW.*.md`, and `.claude/work/` — see §5.
110
+ 5. **Git-ignore** `FLOW.md`, the six harness overlays by name, and `.claude/work/` — see §5.
108
111
 
109
112
  **Two keys are written without being asked**: `agents.fanout_max` (`4`) and `agents.budget_max`
110
113
  (`12`), with their default values, because they are the only brake on what a review costs and a key
@@ -123,7 +126,7 @@ overlay, never the base.
123
126
 
124
127
  ## 4. Write the base and, only when needed, the active overlay
125
128
 
126
- Write compact files at the repo root — every command reads the base and active overlay in every
129
+ Write compact files at the repo root — every command reads every FLOW layer in every
127
130
  phase, so their size is paid on every step:
128
131
 
129
132
  - `FLOW.md` holds repo facts and shared preferences: tracker, git, autonomy, quality commands, cost
@@ -156,9 +159,10 @@ phase, so their size is paid on every step:
156
159
  - The base and overlays are **personal config, not team config** (repo facts mixed with one
157
160
  developer's flow preferences, tools and agents; **no secrets**) — they should not be committed.
158
161
  One `AskUserQuestion`, both parts in the same question:
159
- - The root files not already git-ignored → **offer to add `/FLOW.md` and `/FLOW.*.md` to
160
- `.gitignore`**. This edits a tracked file — confirm before writing. A team wanting the repo-fact
161
- subset can still commit it deliberately. Do not use a recursive pattern: examples under the
162
- plugin must remain visible.
162
+ - The root files not already git-ignored → **offer to add `/FLOW.md`, `/FLOW.claude.md`, `/FLOW.codex.md`, `/FLOW.gemini.md`, `/FLOW.hermes.md`, `/FLOW.opencode.md` and `/FLOW.zcode.md` to `.gitignore`**,
163
+ each by name. This edits a tracked file — confirm before writing. A team wanting the repo-fact
164
+ subset can still commit it deliberately. Never `/FLOW.*.md`: it also hides a context layer
165
+ (`FLOW.<context>.md`, flow-core §0), which a repo commits on purpose. Do not use a recursive
166
+ pattern either: examples under the plugin must remain visible.
163
167
  - Git-ignore `.claude/work/` too — recommended default: ignore it (artifacts are personal working state; teams that want to share them commit deliberately). `git.worktree` not `off` → offer `.worktrees/` in the same gesture.
164
168
  - Suggest `/flow-next` as the next step (it routes to `/flow-feat-start`, `/flow-work-resume` or `/flow-work-status`).
@@ -23,8 +23,9 @@ runs a phase on its own and never advances `meta.json`.
23
23
 
24
24
  ## 1. Look
25
25
 
26
- 1. Identify the active harness. Does `FLOW.md` or its active `FLOW.<harness>.md` exist at the repo
27
- root? An inactive harness's overlay does not configure this session.
26
+ 1. Identify the active harness. Does `FLOW.md`, the context file `FLOW_CONTEXT` selects, or the
27
+ active `FLOW.<harness>.md` exist (flow-core §0)? An inactive harness's overlay, or a context file
28
+ no variable selects, does not configure this session.
28
29
  2. `git branch --show-current`, and whether `.claude/work/*/meta.json` has a `branch` equal to it (also check `worktree` entries, and `.claude/work/_archive/` is ignored).
29
30
  3. `.claude/work/` — how many open works, and their `phase` (from `meta.json`; read `00-summary.md` when present, never the full artifacts).
30
31
  3b. `followups[]` across those works **and** `.claude/work/_archive/*/meta.json`: any entry `accepted` with no `work` started (flow-core §7).
@@ -34,7 +35,7 @@ runs a phase on its own and never advances `meta.json`.
34
35
 
35
36
  | Situation | Say | Propose |
36
37
  |---|---|---|
37
- | Neither base nor active overlay | "This repo is not configured for flow on this harness yet." One line on what the FLOW config is (personal config, auto-detected). | `/flow-init` |
38
+ | No FLOW layer present | "This repo is not configured for flow on this harness yet." One line on what the FLOW config is (personal config, auto-detected). | `/flow-init` |
38
39
  | A work matches the current branch | Its stop header (flow-core §3: ticket · size · phase · MR #n of N) and the next phase for its size. | `/flow-work-resume` |
39
40
  | No match, but open works exist | Count, and the two most recently updated with their phase. | `/flow-work-status`, or `/flow-feat-start` / `/flow-bug-start` if the user said what they want to do |
40
41
  | No works at all, but an accepted follow-up is waiting | "Nothing in flight — but `<TICKET>` F1 was accepted and never started: `<title>`." | `/flow-feat-start <ticket>` (or `/flow-bug-start`) for that follow-up · `/flow-feat-start` for something else |
@@ -43,7 +44,7 @@ runs a phase on its own and never advances `meta.json`.
43
44
  - The SessionStart hook (`hooks/session-start.sh`) has already printed the first two rows of this table's second case — the header and what the last session was doing — off disk, without reading a ticket or an artifact. Say them again anyway: `next` is where the user asked, and a line they scrolled past is not an answer.
44
45
  - An `accepted` follow-up exists **and** other works are open → do not reroute; add one line naming it after the options. It is a standing commitment, not an interruption.
45
46
  - Dirty tree and no matching work → mention it in one line ("uncommitted changes on `<branch>`, no work is tracking them") before the options; `start` will warn again.
46
- - A base or active overlay is present but `/flow-doctor` has never been run in this session and the
47
+ - A FLOW layer is present but `/flow-doctor` has never been run in this session and the
47
48
  git host CLI is not on `PATH` → add `/flow-doctor` as a secondary option.
48
49
  - In `autonomy.mode: guided`/`auto`, the route is still asked: `next` is where a session begins, and the mode governs what happens *inside* a phase, not which work the user wants to pick up.
49
50
 
@@ -24,8 +24,11 @@ This system **orchestrates** the project's existing sub-agents and skills (it do
24
24
  commands, code conventions, and observability profile.
25
25
  - The active `FLOW.<harness>.md` is an optional sparse overlay (`claude`, `codex`, `opencode`,
26
26
  `gemini`, `hermes`, or `zcode`) for model names, agents, skills, orchestration, knowledge tools, or any other value that
27
- differs on that harness. Every command reads the base and then the active overlay in step 0;
27
+ differs on that harness. Every command reads the base, the context layer below, and then the
28
+ active overlay in step 0;
28
29
  existing repos with only `FLOW.md` behave exactly as before.
30
+ - `FLOW_CONTEXT=<name>` in the environment adds `FLOW.<name>.md` between the two: a layer the repo
31
+ commits for where flow runs (CI, a server, an orchestrator), with the overlay's merge rules.
29
32
  - An overlay key replaces the base even when explicitly empty; an absent key inherits it. Lists
30
33
  replace whole lists. Overlay `conventions` are added after base conventions. In the rest of this
31
34
  document, `FLOW.md` means the effective merged configuration unless a write target is explicit.
@@ -110,6 +113,9 @@ This system **orchestrates** the project's existing sub-agents and skills (it do
110
113
  "note": "reason if closed/superseded; empty otherwise"
111
114
  }
112
115
  ],
116
+ "ticket_deps": [
117
+ { "ticket": "#253", "why": "one line, what that ticket brings that the base branch lacks" }
118
+ ],
113
119
  "related_repos": [
114
120
  { "repo": "sibling-project", "scope": "what's needed there", "status": "pending" | "in_progress" | "done", "contract_handoff": "none" | "pending" | "published → <location>" }
115
121
  ],
@@ -158,6 +164,7 @@ This system **orchestrates** the project's existing sub-agents and skills (it do
158
164
  Two fields for the review because they are two facts. `reviewed_sha` used to be `git rev-parse HEAD` at the end of the phase, which by then held the round's own fixes — so `ship` compared a sha against itself and reported a match over code no reviewer had read. Read by `ship` at pre-flight against `HEAD`: a delta of test files and this work's own folder passes with a note in `06-review.md`; anything else stops and asks in every autonomy mode. Empty is not a mismatch; `fixed_sha` set with `reviewed_sha == HEAD` is one. `review` also reads `reviewed_sha` back as **its own base** on a re-review, so the second round reads the delta instead of the whole branch.
159
165
  - **`respond_rounds`**: rounds of `/flow-work-respond` on an MR/PR. `/flow-work-respond §1` reads it against `quality.respond_max_rounds` (empty = 3) and refuses the round that would exceed it, handing the open threads back to the user.
160
166
  - **`related_repos`**: the **other repos a task touches**. Captured at `/flow-feat-start` / `/flow-bug-start` §cross-repo, refined at `design`/`plan`, reminded at `ship`, shown by `daily`/`resume`/`status`. flow only notes and reminds — never touches the other repo. `[]` for single-repo.
167
+ - **`ticket_deps`**: the **other tickets this study cannot be built without** — something the design needs that is not on the base branch and that another ticket brings (`/flow-feat-design` §5.1, `/flow-bug-investigate` §4.1). Read at the two exits of a study: `/flow-work-handoff` §5 writes a `Depends on <ticket>` line per entry into the ticket body, and an unattended study run passes `--depends-on N` per entry on its `done` (flow-core §2.1). Not `mrs[].depends_on`, which orders this work's own MRs/PRs. Written whole each time `design` (or `investigate`) runs, and removed when an unattended study is rewound. `[]` or absent when the study depends on nothing.
161
168
  - **`contract_handoff`**: whether the sibling knows **what shape to build against** (`scope` is prose; distinct from `status`). `none` — consumes no contract declared here. `pending` — consumes one, not handed over yet. `published → <location>` — published where that side reads it (normally the tracker ticket; `/flow-feat-ship` §6.3), picked up by the sibling's `/flow-feat-start` §3.6.
162
169
  - **`followups`**: work a phase deliberately did **not** do here — a neighbouring defect found while building, a piece put out of scope while planning, a risk recorded but not mitigated, an edge case left unchecked, a prevention action from a postmortem. Written by the phase that parks it (asks nothing) when it clears the bar of flow-core §7, triaged **once** at `ship`'s Close behind a skeptic and a ceiling on how many may become questions, published in the MR/PR description while still open, and surfaced by `status`/`daily`/`next` — including from `_archive/` — until `declined` or `done`. Shape and rules: flow-core §7. `[]` when the work deferred nothing.
163
170
  - **`defaults_used`**: an empty `FLOW.md` key a phase resolved with its default instead of asking — written in `guided`/`auto`, where asking would breach the never-a-question contract (flow-core §0). Not an error and not deferred work: a record, aggregated by `/flow-doctor` across every work including `_archive/`, so a key that keeps defaulting can be pinned once instead of decided every time. `[]` when nothing defaulted.
@@ -242,7 +249,7 @@ Two signals arrive on an open MR/PR, each with its own cross-cutting loop (feat
242
249
 
243
250
  ## Cross-cutting commands
244
251
 
245
- - `/flow-next` — the entry point: no base or active overlay → init; work on the current branch →
252
+ - `/flow-next` — the entry point: no FLOW layer → init; work on the current branch →
246
253
  resume; otherwise status.
247
254
  - `/flow-work-daily [question]` — the **work assistant** (daily standup), read-only. **Local** (`.claude/work/` + git) + **forge** (open MRs/PRs, reviews awaiting you, red CI, unmergeable, unresolved threads via `git.cli`) + **tracker** (assigned tickets, priority changes via `tracker.tool`); where they cross, concrete commands (`/flow-feat-start`, `/flow-work-green`, `/flow-work-respond`). No argument → *yesterday · today · blockers*; a question → just that. External sources best-effort, never blocking; the only write is a "last seen" marker, like `/flow-news`.
248
255
  - `/flow-work-status` — all works in `.claude/work/`, current phase, divergence with git.
@@ -146,13 +146,27 @@ the ticket read it there, never in the work folder; the receiver does not parse
146
146
  <!-- end flow-study -->
147
147
  ```
148
148
 
149
- Criteria keep their literal values. The plan lists each MR/PR with what it covers and what it
150
- waits on; a bug's plan is its single fix.
149
+ Criteria keep their literal values. `## Design in brief` ends with each `meta.json.ticket_deps`
150
+ entry and its why — `Depends on #253: <why>` — so whoever approves the study sees what it waits
151
+ for; an unattended study's `done-summary.md` is this block, so it carries them too. The plan
152
+ lists each MR/PR with what it covers and what it waits on; a bug's plan is its single fix.
151
153
  - **The new body**: the body read above with the block between the two markers replaced — or, with
152
- no markers yet, the block appended after a blank line. Written to a `mktemp` file outside the
154
+ no markers yet, the block appended after a blank line. Then, for each `meta.json.ticket_deps`
155
+ entry (`/flow-feat-design` §5.1) whose line is not already a line of that body — same text,
156
+ ignoring case and surrounding whitespace — one line after the end marker, in `ticket_deps` order:
157
+
158
+ ```
159
+ Depends on #253
160
+ ```
161
+
162
+ `#253` being the entry's `ticket` as it stands. Outside the markers so a later rewrite of the
163
+ block leaves it alone, and never removed: a line a person wrote by hand looks exactly like one
164
+ flow wrote, and the convention is theirs too. Written to a `mktemp` file outside the
153
165
  tree — `{BODY_FILE}` — so nothing of it can be committed later.
154
- - **Show the block and ask** with `AskUserQuestion`, **in every mode**: it writes to a shared
155
- tracker. **Write it** · **Skip**. Failure → its message in one line; the push stands.
166
+ - **Show the block, and the `Depends on` lines it adds, and ask** with `AskUserQuestion`, **in
167
+ every mode**: it writes to a shared tracker. A `Depends on` line already in the body, outside the
168
+ markers, that no entry names — a dependency a revised study dropped, or one a person added — is named in the same
169
+ question and left in place: whether it still holds is theirs to say. **Write it** · **Skip**. Failure → its message in one line; the push stands.
156
170
 
157
171
  ## 6. Close
158
172
 
@@ -65,7 +65,7 @@ of truth, and an argument that disagrees with it is ignored and named in the log
65
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
66
  | `review` · `pipeline` · `conflict` | none | `blocked` — there is no work of this ticket to answer for |
67
67
 
68
- **The work's branch, on `start` and `study`.** The current branch is `meta.json.branch` → nothing to do. It is
68
+ **The work's branch, on `start` and `study`.** The current branch is `meta.json.branch` → no switch. It is
69
69
  not — a study made on another machine arrives on the ticket's `base`, a run that died before its
70
70
  closing order is relaunched there — then, in this order:
71
71
 
@@ -88,6 +88,21 @@ closing order is relaunched there — then, in this order:
88
88
  `meta.json.branch` = it, `meta.json.base` = that base, `worktree` and `stacked_on` = `null` — paths and parents from the
89
89
  other machine mean nothing here — and record `{ "key": "unattended:rehomed", "default": "<old branch> → <name> from <base>", "phase": "run" }`.
90
90
 
91
+ **On `start`, a study's branch catches up with its base** — once on the work's branch, the "no
92
+ switch" case included, and only while no build or fix has begun (neither `05-implementation.md` nor
93
+ `04-fix.md` exists). Every command below runs in the work's own checkout — step 2's worktree when
94
+ that is where it lives. A study writes no code, so its branch still sits where the base was when the
95
+ study began; an approval that waited for the tickets the study depends on (`meta.json.ticket_deps`)
96
+ would otherwise build on a base that lacks them. `<base>` = `meta.json.base`, empty →
97
+ `git.default_base`: `git fetch origin <base>`, then `<ref>` = `origin/<base>`; the fetch failing
98
+ with a remote configured → `blocked`, since a stale ref would leave the build on the old base
99
+ unnoticed. No remote → the local `<base>`. `git merge-base --is-ancestor HEAD <ref>` and `HEAD` is not
100
+ `<ref>` → the branch holds no commit of its own and the base moved: `git merge --ff-only <ref>`, and
101
+ record `{ "key": "unattended:base-caught-up", "default": "<old short sha> → <new short sha> on
102
+ <base>", "phase": "run" }`. The fast-forward fails → `blocked`, its message as the reason. Not an
103
+ ancestor → it holds commits a previous run made: leave it as it is — bringing the base into work in
104
+ progress is the orchestrator's (flow-core §2.1).
105
+
91
106
  **A person's changes to a study, on `study`** (flow-core §2.1: they rewind it). The work's branch
92
107
  first, as above. `<work>/study-revision.md` holds the reply, as the row above wrote it. Each step
93
108
  can be run again: a run that dies part-way is finished by the next relaunch, whatever it serves.
@@ -111,7 +126,8 @@ can be run again: a run that dies part-way is finished by the next relaunch, wha
111
126
  `study-revision.md` and earlier `before-*/` folders into `<work>/before-<id7>/` — never
112
127
  overwriting a name already there — so no artifact, summary or agent answer of the discarded study
113
128
  leaks into the next. Then `meta.json`: `phase` = `context`, `phases_done` = `["context"]`, `mrs`
114
- removed (the row that blocks a work past the study guarantees nothing was built), `notes`
129
+ removed (the row that blocks a work past the study guarantees nothing was built), `ticket_deps`
130
+ removed (the redone study finds its dependencies again), `notes`
115
131
  emptied, and every `followups[]` entry a study phase wrote (`source` `design`, `plan` or
116
132
  `investigate`) removed.
117
133
  5. **Re-size**: estimate the size again with `/flow-feat-start` §4's table (`/flow-bug-start`'s for