Carries one phase from the owner's final go on the discuss to its close: critiques, plan, execution by parts, UI walk, review and close. Use when the discuss hands over a signed-off phase, on "continue", and to retake a job the factory returned.
Installs into .claude/skills of the current project.
Sponsors
SSkills DirectorySkills Directory
Is that skill safe to install?
SSkills DirectorySkills Directory
Know which skills are safe — weekly.
Are you the author of Session?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/danitrrga-session)
---
name: session
description: Carries one phase from the owner's final go on the discuss to its close: critiques, plan, execution by parts, UI walk, review and close. Use when the discuss hands over a signed-off phase, on "continue", and to retake a job the factory returned.
arguments: [target]
user-invocable: false
---
<!-- referent: pstack plugins/pstack/skills/poteto-mode/playbooks/session-pickup.md @36885ea (step 0: read the trail, redo nothing) and pause-safely.md @36885ea (the cut: nothing irreversible, all on disk, the first action on resuming) -->
<!-- referent: pstack plugins/pstack/skills/poteto-mode/playbooks/multi-phase-plan.md @36885ea and orchestrate.md @36885ea (the walk through parts; one writer per file) -->
<!-- Differs from the referents: they have no owner gates, no stage table and no return to the discuss; the gates, the stage rows, the budget rule and the phase branch are this repo's. The steps are numbered as the tree's session lane; where the code names a command, the code rules. -->
You carry one phase from the owner's final go on the discuss to its close, alone: no agent reads a playbook, and the owner is asked only at the gates below. This text is your workflow. It reaches you through the `Skill` tool, and its steps are your instructions, calls to other skills included.
Your argument is `$ARGUMENTS`: a phase folder (absolute path), `retake <KEY>`, or empty for "continue". `$target` holds only its first word, so read the whole string from `$ARGUMENTS`.
## Fixed rules
1. **Who speaks.** Only you speak with the owner; an agent that needs an answer returns the question. You write no code and read no long file (the body of `plan.md` or `postmortem.md`, a diff, a transcript): an agent reads it and returns paths and counts, because your context must not compact before the post-mortem.
2. **Agents.** Launch with `Agent` (every agent below, `state`, `decisions` and `skill-proposer` included): `subagent_type` `fwx:<role>` (the type gives its colour) and `model` printed by `fwx model <role> <size>`, the size being `size_tag` of `premortem.md` (`normal` until it exists). The prompt gives the absolute paths of the phase's `context.md` and `decisions.tsv`, what to return (paths and counts) and the language of the conversation (`<language>` everywhere below is the language the owner writes in). A launch returns at once: read its result after its completion notice. A dead agent or an empty return is not "no findings": launch it once more, and if it fails again tell the owner it did not run.
3. **Stages.** Only you write a stage, only with `fwx stage <folder> <stage> --why "<text>"`, on the phase folder (a part is a word in the text, not a folder). A refusal exits 1 with `<a> -> <b> is not in data/stages.json (session)` and writes no row: read it and do not retry, because the table will refuse the same change again. No agent you launch moves a stage, so none of your prompts names that command. Announce each stage with the heading `### fwx ▸ <STAGE>` (the stage name in capitals). Write nothing in `.fwx/` by hand: its files come from commands or from their one agent (`decisions` writes `decisions.tsv`; `state` writes `state.md`); the two exceptions are the `context.md` of a retaken job (step 3 of `references/factory-return.md`) and the `report-<n>.md` you save from the text `state` returns (step 8), because the harness refuses a subagent's Write of a report.
4. **Commits of `.fwx/`**, before each `execute` and at the close; `main_checkout` is a key of `fwx state resolve --json`. When `git check-ignore -q .fwx/PROJECT.md` succeeds there (the history lives on the data side), run `cd <main_checkout> && forge commit -m "<message>" .fwx`. Otherwise run `git -C <main_checkout> add .fwx && git -C <main_checkout> commit -m "<message>" -- .fwx`: local, never pushed (a default branch that requires a pull request takes it on the phase branch, in its worktree).
5. **Issues.** Only you open them: `fwx linear create --template general` with one JSON object on stdin (`title`, `context`, `expected`, `origin`) and no labels, because a label would hand the issue to the factory. When the owner says the repo is a test repo, the title starts `[test] `. No `linear_project` or no key: say so; do not keep a local list, because issues live in Linear.
6. **Questions.** Ask the owner only what needs his taste or direction. What has a clearly better option you decide and list under Assumptions in the part's report. A question is numbered, each option says what it implies, and it carries no recommendation. Quote his answer word for word when you record it.
7. **Budget.** Run `fwx budget --json` at the start of each step and before each wave. `context.used_percentage` above 50: an agent does the heavy reading that is left, and before the plan step 2 also asks about splitting the topic. `quota.week_tight` true: one line before the wave ("the week is tight: X% used, Y% of the week gone"), then launch it anyway, because quota never stops or delays a wave. A `null` percentage or quota `"unknown"` means no threshold and no warning.
8. **Skills and workflows.** Call `fwx:discuss`, `fwx:pre-mortem`, `fwx:plan` and `fwx:post-mortem` with the `Skill` tool. If a call is refused, read `${CLAUDE_PLUGIN_ROOT}/skills/<name>/SKILL.md` and do its steps yourself (a skill file is the one long file you read, because its steps are yours): the text is the same either way. A skill you call runs in this conversation and is not an agent: the line it tells you to end with is its result for you to read, not the end of your turn, so carry on at the next step of this text. Launch `fwx:execute` and `fwx:ui-walk` with the `Workflow` tool, `name` and `args` as a literal JSON object (never a string, which the workflow cannot read fields from); the call returns at once, so wait for its completion notice. After a compaction, redo step 0.
**Phase branch.** `fwx/[<subproject>/]<milestone>-<phase folder name>`, from `project.default_branch` of `.claude/fwx.json`. Make it with `git worktree add <main_checkout>/.claude/worktrees/<name> -b <branch> <default_branch>` and work from that folder with `cd`: `fwx wave` runs there, while `.fwx/` stays in `<main_checkout>`, where this session started and may write. `fwx wave prepare` (step 5) runs the project's `worktree_setup` in that folder and stops on its failure, so `fwx wave setup` there is only for seeing a failing setup before anything else is done: it prints `worktree setup: 1 command ran (log <path>)` (`2 commands ran` and so on; `already done ...` when nothing was owed; `no worktree_setup configured`), and on exit 1 `fwx wave setup: worktree setup failed: <command> (exit N, log <path>)`, on exit 2 another one-line reason. Stop on either and give the owner the line as printed. The owner's own checkout never changes branch and nothing merges into the default branch, because that merge is the owner's.
## Steps
0. **Where you are.** With `retake <KEY>`, follow `${CLAUDE_PLUGIN_ROOT}/skills/session/references/factory-return.md` and stop here. Run `fwx state resolve --json`; a path in `$ARGUMENTS` is the phase. With no path and exactly one open phase, that is it; with none or several, list `candidates` as a numbered question. You own the resume point: read the trail, redo nothing. Read the last `stage` rows of the phase's `audit.tsv` (`grep -P '\tstage\t' <phase>/audit.tsv | tail -4`), then `context.md`, `decisions.tsv`, the frontmatter of `plan.md` if it exists and the latest `state.md`; with a branch in the last `executing` row, also `git log <default_branch>..<branch>` and `git worktree list` (paths read from it, never typed). Go to the step of the last stage: none or `discuss` 1; `premortem` 1; `planning` 2; `postmortem` 3; `executing` 5 on that part and branch (it is the cut: execute again, do not write the row again); `reviewing` 6 when the part has UI, else 8; `ui-walk` 6; `phase-review` 8; `closed` or `cancelled`: say so and stop. The last stage row is already written, so skip the "Stage ..." sentence of the step you resume at (the table refuses a stage after itself).
1. **Pre-mortem.** Stage `premortem`. Call `fwx:pre-mortem` with `<phase folder>; language: <language>`. Its last line is `{status, reason, phase_dir}`: `failed` say so and stop; `back-to-discuss` step 7; otherwise the first word of `reason` is the verdict. `ok`: step 2. `objections`: read `## Findings` of `premortem.md` and give the owner a short numbered block; record his answers by the `decisions` agent (`source` `premortem r<N>`); then step 2.
2. **Plan.** Budget first (rule 7). With `context.used_percentage` above 50 and no `planning` row yet in `audit.tsv` (a replan after step 4 does not ask again), do not write stage `planning` yet, because the table has no way from `planning` back to the discuss: propose in one line to split the topic into more phases and end your turn for his answer. Yes: step 7. No: go on. Stage `planning`. Call `fwx:plan` the same way; `failed` say so and stop. The planner writes one `plan.md` per part and `fwx plan check` has passed.
3. **Post-mortem.** Stage `postmortem`. Call `fwx:post-mortem` the same way. `failed` say so and stop; `back-to-discuss` step 7. Read only the frontmatter and `## Findings` of `postmortem.md`. The first word of `reason` is the verdict, as in step 1. `ok`: step 4 with no stop. `objections`: step 4 with a stop.
4. **Go and phase branch.** No objections: one status line (size, parts, agents, branch) and go on, with no question. Objections: one message with size, parts and agents, the verdict and the numbered objections, then these options:
1. Execute here: the parts run in this session.
2. Execute in a new session: this one stops after the stage row below, and "continue" in a fresh one picks the plan up from disk.
3. Accept the objections: they are recorded (`source` `postmortem r<N>`) and a new planner replans (step 2).
4. His intention was misread: step 7.
On 1 or 2, or with no objections: make the phase branch and worktree, write stage `executing` with `part 1 branch <branch>` and commit `.fwx/` (rule 4). On 2 stop there and tell him the first action on resuming: a new session, "continue".
5. **Execute a part.** The part folder is its subphase folder (`subphases` of `fwx state resolve --json`), or the phase folder when there are none. For a part after the first, or a correction, write stage `executing` first (`part <N> branch <branch>`, or `part <N> corrections`); on a relaunch it is already written. Budget, then commit `.fwx/`. From the worktree run `fwx wave prepare --part-dir <part> --plane session --branch <branch>` (add `--unattended` when the owner says he is leaving); it prints the `args`. Exit 1 prints a needs-owner line: the base checks fail, no round was spent, so ask him. Exit 2: say the reason on stderr and stop. Then launch `Workflow` with `{"name": "fwx:execute", "args": <that JSON object>}` and wait. It returns `{status, reason, phase_dir, details}`:
- `done`: run `fwx wave summary --run <details.run>`. Any exit but 0 means the gate did not pass: treat it as `failed`, whatever the runner said. Otherwise open an issue (rule 5) for each entry of `details.outside`, write stage `reviewing` with `part <N>`, and go to step 6 when a task of the part has `ui: true` (read it from the frontmatter of the part's `plan.md`), else step 8.
- `failed`: the rounds ran out. Tell the owner what was tried (`reason`, `details.tried`). His correction: `fwx rounds <part> --reset "<his words>"`, then launch again. Without one the phase stays open; stop.
- `needs-owner`: `verify could not run` in `reason`: find the cause first (environment, missing tool); fix it if you can and relaunch, no round spent; ask only when you cannot. `protected path`: always ask, with the paths and the security findings of `details`; with his go write stage `reviewing`, do not relaunch (the code already passed review), and a change he asks for enters as a correction in step 8. `every task of the part is already on the phase branch`: run the `prepare ... --from gate` command the reason prints and launch again. Any other reason (an executor's question, a red base): a numbered question, his answer recorded by `decisions` (`source` `execute question`), then `prepare` and launch again; the rounds are not reset.
A correction from the owner, or a diff to apply, reaches `execute` as findings: write a JSON list (`id`, `file`, `line` 0, `claim` his words, `evidence` "owner review of part <N>", `severity` `high`) to a scratch file made with `mktemp`, pass it as `--fix <file>` to `prepare`, and remove it afterwards.
6. **UI walk and its fixes.** Only when a task of the part has `ui: true`. Stage `ui-walk` with `part <N>`. Launch `fwx:ui-walk` with `args` `{"phase_dir", "part", "part_dir", "plan", "context", "decisions", "config", "work_branch", "repo", "base", "round": 1, "app": null, "models": {"breaker", "critic", "verifier", "runner"}, "recheck": null}`, every path absolute, `repo` the worktree, `base` the `base` of `prepare`, `models.breaker` from `fwx model ui-walker small`, `models.critic` from `fwx model ui-walker normal`, `models.verifier` from `fwx model ui-verifier normal`, `models.runner` from `fwx model executor small`. It returns `details.fix_file`, `counts`, `contradicted_file` and `run_dir`. Read `status` and `reason` first: `failed`, or a `reason` that is not empty (the control was not found, a browser could not be closed), is not "no findings" (`fix_file` is null when nothing was verified). Tell the owner the `reason` as printed, how many findings were collected but not verified and where (`details.unverified`: a tramo and its findings files each) and `details.gaps`; the walk is not passed, and the part's report says so. While `fix_file` has findings and rounds remain: `fwx wave fix-round --part-dir <part> --why "<findings>"` (it spends the round and exits 1 when none are left: then `failed`, tell the owner), `fwx wave prepare ... --fix <fix_file>`, `fwx:execute` (one commit per finding), then `fwx:ui-walk` again with `recheck` set to the path of that fix file. The fix rounds write no stage row. A finding the walk marks `CONTRADICTED` is not fixed: it goes to the review. Then step 8.
7. **Back to the discuss.** Propose it in one line and say why: after a critique, the `reason` of its status line carries the critique's own sentence after the colon (a bare `back-to-discuss` has none: say it gave no reason, and leave the critique file unread, rule 1). On his yes: the `decisions` agent writes the row that changes the earlier decision (`support` `approved`, `supersedes` its id), then write stage `discuss` with `<where you came from>: <reason>` (the table allows it from `premortem`, `postmortem`, `ui-walk` and `phase-review`; from `executing` or `reviewing` write `phase-review` first) and call `fwx:discuss <phase folder>`. If the call is refused, rule 8 applies.
8. **Review of the part.** Stage `phase-review` with `part <N>`. On the last part of a UI phase, launch `skill-proposer` first (inputs: the part's `context.md`, `decisions.tsv`, `plan.md`, the branch and the base sha of the part's `executing` row); it returns `NONE: <reason>` or a block and a patch. Make the report as `${CLAUDE_PLUGIN_ROOT}/skills/session/references/part-report.md` says, except on a resume (step 0): then the latest `report-<n>.md` of the part folder is the one the owner was shown, so use it and launch `state` only when there is none. Paste the file's text to the owner before you ask anything, then: the `consider` findings (`details.findings.consider`, each with its severity; they are not fixed), the `Noticed:` line if there is one, and for each screenshot an `xdg-open <absolute path>` line in its own code block, because the owner does not see tool output and opens the files himself. The close does not rewrite the report, because it is what the owner reviewed.
Read `ui` and `review` of the part's tasks in the frontmatter of its `plan.md`: a part with a `ui: true` task or a `review: blocking` task blocks on his review. Then you end your turn once, with the question that review is, and start neither the next part nor the close before his answer. For a part with a UI walk the question is the review page: follow `${CLAUDE_PLUGIN_ROOT}/skills/session/references/ui-review.md`, which ends your turn after the report (with `"items": 0` there is no page, so ask the numbered question). Otherwise the question is numbered, each option says what it implies, and it carries no recommendation: 1. it is good, the next part starts (or the close after the last); 2. there is an implementation problem, the part is corrected; 3. the intention was misread, back to the discuss. A part that blocks on neither goes on to the next part and takes his reply when it comes.
A rejection on the page stops you there; with none, treat the part as good.
His answer: good: next part (step 5 for part N+1) or step 9 after the last. An implementation problem: `fwx rounds <part> --reset "<his words>"`, stage `executing` (`part <N> corrections`) and `execute` with the correction (step 5). A problem of intention: step 7. Asynchronous review: a late objection is recorded at once with `fwx rounds <part> --reset "<his words>"` (on disk, so a cut keeps it) and runs as a correction of that part at the next boundary. The phase closes only when no part has a reset after its last `phase-review` row. An accepted proposer patch goes to `execute` as a correction of the last part.
Next part left: step 5. None: step 9.
9. **Close.** Follow `${CLAUDE_PLUGIN_ROOT}/skills/session/references/closing.md`. There is no closing conversation: the report is already written.