continuous-refactoring 0.2.0__tar.gz → 1.0.0__tar.gz
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.
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/.gitignore +2 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/PKG-INFO +91 -28
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/README.md +90 -27
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/pyproject.toml +1 -1
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/cli.py +158 -65
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/commit_messages.py +6 -2
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/decisions.py +15 -20
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/effort.py +45 -8
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/failure_report.py +68 -2
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/git.py +1 -1
- continuous_refactoring-1.0.0/src/continuous_refactoring/log_mirroring.py +11 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/loop.py +351 -77
- continuous_refactoring-1.0.0/src/continuous_refactoring/migration_cli.py +717 -0
- continuous_refactoring-1.0.0/src/continuous_refactoring/migration_consistency.py +528 -0
- continuous_refactoring-1.0.0/src/continuous_refactoring/migration_tick.py +950 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/phases.py +13 -5
- continuous_refactoring-1.0.0/src/continuous_refactoring/planning.py +1225 -0
- continuous_refactoring-1.0.0/src/continuous_refactoring/planning_publish.py +688 -0
- continuous_refactoring-1.0.0/src/continuous_refactoring/planning_state.py +1044 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/prompts.py +80 -29
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/refactor_attempts.py +51 -16
- continuous_refactoring-1.0.0/src/continuous_refactoring/review_cli.py +212 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/routing.py +40 -21
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/routing_pipeline.py +170 -70
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/scope_candidates.py +44 -24
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/scope_expansion.py +51 -15
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/targeting.py +15 -18
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/conftest.py +77 -26
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_cli_init_taste.py +48 -37
- continuous_refactoring-1.0.0/tests/test_cli_migrations.py +1744 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_cli_taste_warning.py +35 -23
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_cli_upgrade.py +56 -62
- continuous_refactoring-1.0.0/tests/test_cli_version.py +39 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_commit_messages.py +10 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_config.py +6 -20
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_continuous_refactoring.py +9 -2
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_decisions.py +85 -0
- continuous_refactoring-1.0.0/tests/test_effort.py +143 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_failure_report.py +216 -7
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_focus_on_live_migrations.py +448 -30
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_git.py +60 -29
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_loop_migration_tick.py +872 -38
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_main_entrypoint.py +5 -4
- continuous_refactoring-1.0.0/tests/test_migration_consistency.py +305 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_no_driver_branching.py +8 -18
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_phases.py +133 -6
- continuous_refactoring-1.0.0/tests/test_planning.py +1551 -0
- continuous_refactoring-1.0.0/tests/test_planning_publish.py +611 -0
- continuous_refactoring-1.0.0/tests/test_planning_state.py +871 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_prompts.py +283 -8
- continuous_refactoring-1.0.0/tests/test_refactor_attempts.py +166 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_routing.py +90 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_run.py +829 -128
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_run_once.py +156 -53
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_scope_candidates.py +43 -10
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_scope_expansion.py +136 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_scope_loop_integration.py +211 -6
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_scope_selection.py +28 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_targeting.py +14 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_taste_interview.py +26 -12
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_taste_refine.py +6 -10
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_taste_upgrade.py +21 -15
- continuous_refactoring-0.2.0/src/continuous_refactoring/migration_tick.py +0 -468
- continuous_refactoring-0.2.0/src/continuous_refactoring/planning.py +0 -588
- continuous_refactoring-0.2.0/src/continuous_refactoring/review_cli.py +0 -136
- continuous_refactoring-0.2.0/tests/test_cli_review.py +0 -539
- continuous_refactoring-0.2.0/tests/test_effort.py +0 -54
- continuous_refactoring-0.2.0/tests/test_planning.py +0 -579
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/LICENSE +0 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/__init__.py +0 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/__main__.py +0 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/agent.py +0 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/artifacts.py +0 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/config.py +0 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/migration_manifest_codec.py +0 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/migrations.py +0 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/fixtures/claude_stream_json/selection.stdout.log +0 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_claude_stream_json.py +0 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_e2e.py +0 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_migrations.py +0 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_prompts_scope_selection.py +0 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_run_once_regression.py +0 -0
- {continuous_refactoring-0.2.0 → continuous_refactoring-1.0.0}/tests/test_wake_up.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: continuous-refactoring
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: Continuous refactoring loop for AI coding agents
|
|
5
5
|
Project-URL: Repository, https://github.com/bigH/continuous-refactoring
|
|
6
6
|
Project-URL: Issues, https://github.com/bigH/continuous-refactoring/issues
|
|
@@ -32,6 +32,8 @@ Small, test-gated cleanup commits by an AI coding agent.
|
|
|
32
32
|
|
|
33
33
|
Think of it as a supervised janitor loop: the agent proposes a cleanup, your tests decide if it stays.
|
|
34
34
|
|
|
35
|
+
Here's [an article](https://artisincode.com/essays/how-i-use-unspent-tokens/) I wrote about it.
|
|
36
|
+
|
|
35
37
|
## Install
|
|
36
38
|
|
|
37
39
|
Try it without installing:
|
|
@@ -67,6 +69,10 @@ uv pip install -e .
|
|
|
67
69
|
|
|
68
70
|
That gives you the `continuous-refactoring` command.
|
|
69
71
|
|
|
72
|
+
The CLI itself can be installed without `uv`, but the default validation command
|
|
73
|
+
is `uv run pytest`. Pass `--validation-command pytest` or a project-specific
|
|
74
|
+
script when the target repo does not use `uv`.
|
|
75
|
+
|
|
70
76
|
Maintainers: see the [release checklist](https://github.com/bigH/continuous-refactoring/blob/main/docs/release.md).
|
|
71
77
|
|
|
72
78
|
## Fastest way to get one refactor
|
|
@@ -92,15 +98,18 @@ continuous-refactoring run \
|
|
|
92
98
|
--max-attempts 2
|
|
93
99
|
```
|
|
94
100
|
|
|
95
|
-
That
|
|
101
|
+
That runs up to 10 refactor actions, then stops sooner if the finite target file
|
|
102
|
+
runs out or the loop starts failing. Use `run --focus-on-live-migrations` when
|
|
103
|
+
you want the loop to work only on eligible live migrations; it bypasses target
|
|
104
|
+
selection and `--max-refactors`.
|
|
96
105
|
|
|
97
106
|
## What it does
|
|
98
107
|
|
|
99
|
-
- Resolves
|
|
108
|
+
- Resolves each source action from `--targets`, `--globs`, `--extensions`, or `--paths`, with optional natural-language scoping via `--scope-instruction`.
|
|
100
109
|
- Runs the agent with a refactoring prompt + your "taste" guidelines.
|
|
101
110
|
- Runs your validation command (default: `uv run pytest`).
|
|
102
111
|
- If green and there's a diff, it commits locally and leaves the branch for you to inspect.
|
|
103
|
-
- Repeats until it
|
|
112
|
+
- Repeats until it spends the action budget, exhausts a finite target file, hits the retry budget, or stacks too many failures.
|
|
104
113
|
|
|
105
114
|
## Requirements
|
|
106
115
|
|
|
@@ -119,8 +128,8 @@ continuous-refactoring init --in-repo-taste
|
|
|
119
128
|
|
|
120
129
|
# 2. (Optional) Write your refactoring taste — either edit the file, have an agent interview you,
|
|
121
130
|
# or refine an existing draft collaboratively
|
|
122
|
-
continuous-refactoring taste --interview --with codex --model gpt-5
|
|
123
|
-
continuous-refactoring taste --refine --with codex --model gpt-5
|
|
131
|
+
continuous-refactoring taste --interview --with codex --model gpt-5
|
|
132
|
+
continuous-refactoring taste --refine --with codex --model gpt-5
|
|
124
133
|
|
|
125
134
|
# 3. Do one pass
|
|
126
135
|
continuous-refactoring run-once \
|
|
@@ -136,17 +145,23 @@ continuous-refactoring run \
|
|
|
136
145
|
--sleep 5
|
|
137
146
|
```
|
|
138
147
|
|
|
148
|
+
Active taste agent modes require `--with` and `--model`; taste agent sessions
|
|
149
|
+
always run at fixed `medium` effort.
|
|
150
|
+
|
|
139
151
|
## Subcommands
|
|
140
152
|
|
|
141
153
|
| Command | What it does |
|
|
142
154
|
|---|---|
|
|
143
155
|
| `init` | Registers this directory as a project, creates a default `taste.md`, and can store `--live-migrations-dir` or `--in-repo-taste`. |
|
|
144
|
-
| `taste` | Prints the active taste file path. Add `--interview` to have an agent author it, `--refine` to iteratively improve an existing taste doc, `--upgrade` to refresh stale taste dimensions, `--global` for the shared file, and `--force` to let `--interview` overwrite custom content after writing a `.bak`. |
|
|
156
|
+
| `taste` | Prints the active taste file path. Add `--interview` to have an agent author it, `--refine` to iteratively improve an existing taste doc, `--upgrade` to refresh stale taste dimensions, `--global` for the shared file, and `--force` to let `--interview` overwrite custom content after writing a `.bak`. Active agent modes require `--with` and `--model`, then run at fixed `medium` effort. |
|
|
145
157
|
| `run-once` | Single pass on one resolved target. No retry. If there is a diff and validation passes, it commits locally and prints the diffstat. |
|
|
146
|
-
| `run` | The loop. Iterates
|
|
158
|
+
| `run` | The loop. Iterates refactor actions, retries on failure, and commits successful changes locally. Add `--focus-on-live-migrations` to bypass targeting and work only on eligible live migrations. |
|
|
147
159
|
| `upgrade` | Checks that the global config manifest is current, rewrites it idempotently, and warns if the global taste file is stale. |
|
|
148
|
-
| `
|
|
149
|
-
| `
|
|
160
|
+
| `migration list` | Lists visible migrations as TSV with headers. Add `--status <status>` or `--awaiting-review` to filter, or `--no-headers` for parsing. |
|
|
161
|
+
| `migration doctor <slug-or-path>` | Validates one visible migration's consistency. |
|
|
162
|
+
| `migration doctor --all` | Validates every visible migration plus internal transaction state. |
|
|
163
|
+
| `migration review <slug-or-path>` | Starts staged review for a migration awaiting human review. Requires `--with` and `--model`; review runs at fixed internal `high` effort. |
|
|
164
|
+
| `migration refine <slug-or-path>` | Records feedback for a planning or unexecuted ready migration and runs one staged planning revision. Requires `--message <text>` or `--file <path>`, plus `--with` and `--model`; refine runs at fixed internal `high` effort. Add `--show-agent-logs` to mirror the planning agent. |
|
|
150
165
|
|
|
151
166
|
## Targeting / Useful flags
|
|
152
167
|
|
|
@@ -157,29 +172,56 @@ Target resolution is first-match-wins:
|
|
|
157
172
|
|
|
158
173
|
These flags are not mutually exclusive, but only the highest-priority populated source is used.
|
|
159
174
|
|
|
160
|
-
- `--targets path/to/targets.jsonl` — explicit list; one JSON object per line with `description`, `files`, optional `scoping`, `model-override`, `effort-override`. Effort overrides use `low`, `medium`, `high`, or `xhigh`.
|
|
161
|
-
- `--globs 'src/**/*.py:tests/**/*.py'` — colon-separated globs
|
|
162
|
-
- `--extensions .py,.ts` — shorthand that expands to `**/*.py`, `**/*.ts`; each matched file
|
|
163
|
-
- `--paths a.py:b.py` — literal paths, all treated as one target.
|
|
164
|
-
- `--scope-instruction "clean up the auth module"` — extra free-text scoping. If file
|
|
175
|
+
- `--targets path/to/targets.jsonl` — explicit finite list; one JSON object per line with `description`, `files`, optional `scoping`, `model-override`, `effort-override`. Effort overrides use `low`, `medium`, `high`, or `xhigh`. If `--max-refactors` is omitted, `run` processes the file once and stops.
|
|
176
|
+
- `--globs 'src/**/*.py:tests/**/*.py'` — colon-separated globs matched once against tracked files from `git ls-files`; each refactor action samples one matched file, so files can repeat.
|
|
177
|
+
- `--extensions .py,.ts` — shorthand that expands to `**/*.py`, `**/*.ts` against tracked files from `git ls-files`; each refactor action samples one matched file, so files can repeat.
|
|
178
|
+
- `--paths a.py:b.py` — literal user-provided paths, all treated as one grouped target; each refactor action reuses that group.
|
|
179
|
+
- `--scope-instruction "clean up the auth module"` — extra free-text scoping. If selected file patterns resolve nothing, this becomes the useful fallback context.
|
|
165
180
|
|
|
166
|
-
If
|
|
181
|
+
If `--globs` or `--extensions` match no tracked files and there is no
|
|
182
|
+
`--scope-instruction`, `run` completes successfully with zero refactor actions;
|
|
183
|
+
`run-once` falls back to a no-file `general refactoring` target. `--paths` is
|
|
184
|
+
literal input and is not filtered through `git ls-files`.
|
|
185
|
+
|
|
186
|
+
If you provide none of `--targets`, `--globs`, `--extensions`, or `--paths`,
|
|
187
|
+
then `run` and `run-once` require `--scope-instruction`; the driver still
|
|
188
|
+
random-samples tracked files from `git ls-files` for each action and uses the
|
|
189
|
+
scope text as context for that target.
|
|
167
190
|
|
|
168
191
|
### Migrations & taste flags
|
|
169
192
|
|
|
170
193
|
- `init --live-migrations-dir PATH` — enables the larger-refactoring workflow for this project. The path is stored repo-relative in the project registry and created if missing.
|
|
171
194
|
- `init --in-repo-taste [PATH]` — stores this project's taste file in the repo and remembers the repo-relative path. Defaults to `.continuous-refactoring/taste.md`; re-run `init --in-repo-taste ...` to choose a different path.
|
|
172
|
-
- `
|
|
173
|
-
- `
|
|
195
|
+
- `migration list` — shows visible migrations as TSV with headers; `--awaiting-review` narrows to human-review handoffs and `--no-headers` keeps parser-friendly rows only.
|
|
196
|
+
- `migration doctor <slug-or-path>` / `migration doctor --all` — read-only consistency checks. Doctor reports problems; it does not repair them.
|
|
197
|
+
- `migration review <slug-or-path> --with ... --model ...` — resolves an `awaiting_human_review` migration through a staged workspace at fixed internal `high` effort.
|
|
198
|
+
- `migration refine <slug-or-path> (--message <text>|--file <path>) --with ... --model ... [--show-agent-logs]` — adds user feedback to a planning or unexecuted ready migration and resumes planning through the `revise` step when reopening ready work at fixed internal `high` effort.
|
|
199
|
+
- `taste --refine --with ... --model ...` — opens a collaborative editing session for the taste file. The agent keeps refining until you tell it to write, then the session ends automatically after the settled write.
|
|
200
|
+
- `taste --upgrade --with ... --model ...` — re-interviews for taste dimensions added since your last version. No-op when already current; use `taste --refine` if you want to rework the doc anyway.
|
|
201
|
+
- Taste agent sessions always use fixed `medium` effort.
|
|
174
202
|
- `taste --force` — only applies to `--interview`; it allows a customized taste file to be overwritten after backing it up to `taste.md.bak`.
|
|
175
203
|
|
|
204
|
+
Canonical migration commands:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
continuous-refactoring migration list
|
|
208
|
+
continuous-refactoring migration list --status planning
|
|
209
|
+
continuous-refactoring migration list --awaiting-review
|
|
210
|
+
continuous-refactoring migration list --no-headers
|
|
211
|
+
continuous-refactoring migration doctor <slug-or-path>
|
|
212
|
+
continuous-refactoring migration doctor --all
|
|
213
|
+
continuous-refactoring migration review <slug-or-path> --with codex --model gpt-5
|
|
214
|
+
continuous-refactoring migration refine <slug-or-path> --message "split the risky phase" --with codex --model gpt-5
|
|
215
|
+
continuous-refactoring migration refine <slug-or-path> --file feedback.md --with codex --model gpt-5
|
|
216
|
+
```
|
|
217
|
+
|
|
176
218
|
### Shared `run` / `run-once` flags
|
|
177
219
|
|
|
178
220
|
- `--with`, `--model` — required agent backend/model selection.
|
|
179
221
|
- `--default-effort` — default effort for run calls. Defaults to `low`. Valid labels are `low`, `medium`, `high`, `xhigh`.
|
|
180
222
|
- `--max-allowed-effort` — cap for target overrides and migration escalation. Defaults to `xhigh`.
|
|
181
223
|
- `--repo-root PATH` — repository root; defaults to the current directory.
|
|
182
|
-
- `--validation-command` — defaults to `uv run pytest`.
|
|
224
|
+
- `--validation-command` — defaults to `uv run pytest`. This is parsed with `shlex.split` and run without a shell, so simple commands like `pytest -q` work, but shell syntax such as `cmd && cmd`, pipes, redirects, or leading `VAR=value` assignments is not interpreted. Put compound validation in a script.
|
|
183
225
|
- `--timeout` — per-agent-call timeout in seconds.
|
|
184
226
|
- `--show-agent-logs` / `--show-command-logs` — mirror output to your terminal instead of just logging.
|
|
185
227
|
- `--refactoring-prompt` — override the default refactoring prompt.
|
|
@@ -187,10 +229,11 @@ If you provide none of `--targets`, `--globs`, `--extensions`, or `--paths`, the
|
|
|
187
229
|
|
|
188
230
|
### `run`-only flags
|
|
189
231
|
|
|
190
|
-
- `--max-attempts N` — per-
|
|
191
|
-
- `--max-refactors N` — cap the number of
|
|
192
|
-
- `--
|
|
193
|
-
- `--
|
|
232
|
+
- `--max-attempts N` — per-action retry budget. `1` = no retry, `0` = unlimited (which means permanently broken actions will never give up).
|
|
233
|
+
- `--max-refactors N` — cap the number of refactor actions per run. Required unless you use `--targets` or `--focus-on-live-migrations`.
|
|
234
|
+
- `--focus-on-live-migrations` — bypass target selection and `--max-refactors`; iterate eligible live migrations until they are done, deferred, blocked, or the failure budget trips.
|
|
235
|
+
- `--max-consecutive-failures N` — bail after N actions fail in a row. Default 3.
|
|
236
|
+
- `--sleep SECONDS` — pause between completed actions. Useful when you want a long batch without hammering the repo or your agent budget.
|
|
194
237
|
- `--commit-message-prefix TEXT` — subject prefix for successful refactor or migration-plan commits. Default `continuous refactor`.
|
|
195
238
|
|
|
196
239
|
## Safety behaviors
|
|
@@ -207,13 +250,27 @@ If you provide none of `--targets`, `--globs`, `--extensions`, or `--paths`, the
|
|
|
207
250
|
Each run writes to `$TMPDIR/continuous-refactoring/<run-id>/`:
|
|
208
251
|
|
|
209
252
|
- `summary.json` — rolling status, counts, per-attempt stats
|
|
210
|
-
- `events.jsonl` — structured event log
|
|
253
|
+
- `events.jsonl` — structured event log with call roles such as
|
|
254
|
+
`scope-expansion`, `classify`, `planning.<step>`, `planning.publish`,
|
|
255
|
+
`phase.ready-check`, `phase.execute`, and `phase.validation`
|
|
211
256
|
- `run.log` — human-readable log
|
|
212
257
|
- `attempt-NNN/[retry-NN/]refactor/` — per-attempt agent + test stdout/stderr
|
|
258
|
+
- `baseline/initial/` — baseline validation stdout/stderr before work starts
|
|
259
|
+
- `classify/` — classifier agent stdout/stderr
|
|
260
|
+
- `scope-expansion/` — scope candidates, selection, and bypass reason
|
|
261
|
+
- `attempt-NNN/[retry-NN/]planning/<step>/` — planning agent stdout/stderr for
|
|
262
|
+
migration planning steps
|
|
263
|
+
- `phase-ready-check/` — phase precondition agent stdout/stderr
|
|
264
|
+
- `attempt-NNN/[retry-NN/]phase-execute/` — phase agent and validation logs
|
|
265
|
+
- `migration-probes/action-NNN/` — migration probe logs during normal `run`
|
|
266
|
+
actions, including planning, phase ready-checks, and phase execution
|
|
213
267
|
|
|
214
268
|
Mixed-effort runs are auditable: summaries and call events record the default effort, max allowed effort, requested effort, effective effort, source, and whether the request was capped.
|
|
215
269
|
|
|
216
|
-
The path prints at startup. Grep it when something goes sideways.
|
|
270
|
+
The path prints at startup. Grep it when something goes sideways. Failed
|
|
271
|
+
non-commit decisions also write durable XDG snapshots under the project failure
|
|
272
|
+
directory, usually
|
|
273
|
+
`~/.local/share/continuous-refactoring/projects/<uuid>/failures/`.
|
|
217
274
|
|
|
218
275
|
## Taste files
|
|
219
276
|
|
|
@@ -222,7 +279,7 @@ The taste file is a short bullet list of your refactoring preferences. It gets i
|
|
|
222
279
|
- Project taste: `~/.local/share/continuous-refactoring/projects/<uuid>/taste.md`, or the repo-local path chosen with `init --in-repo-taste [PATH]`
|
|
223
280
|
- Global taste: `~/.local/share/continuous-refactoring/global/taste.md`
|
|
224
281
|
|
|
225
|
-
Project taste wins over global. Use `taste` to print the active path, `taste --interview
|
|
282
|
+
Project taste wins over global. Use `taste` to print the active path, `taste --interview --with ... --model ...` to bootstrap one, `taste --refine --with ... --model ...` to rework it with an agent, or edit the file directly any time.
|
|
226
283
|
|
|
227
284
|
## Larger refactorings
|
|
228
285
|
|
|
@@ -241,7 +298,7 @@ This tells the CLI where to store migration artifacts. The path is repo-relative
|
|
|
241
298
|
Each `run` / `run-once` tick now checks for eligible migration work before falling back to single-commit cleanups:
|
|
242
299
|
|
|
243
300
|
1. **Classify** — a classifier agent reads the target and decides: `cohesive-cleanup` (one-shot path) or `needs-plan` (migration path).
|
|
244
|
-
2. **Plan** — for `needs-plan` targets,
|
|
301
|
+
2. **Plan** — for `needs-plan` targets, each automation action runs exactly one planning step: approaches, pick-best, expand, review, optional revise/review-2, then final-review. Accepted steps update `.planning/state.json`, store stdout under `.planning/stages/`, and publish through a staged transaction. Failed current-step output stays in run artifacts and is not resume input.
|
|
245
302
|
3. **Execute** — each phase is a self-contained unit of work. The tick picks the oldest eligible migration, checks whether its current phase precondition is satisfied, and executes it on the current branch. Phase completion is judged against the phase file's `## Definition of Done`; commit message identifies the migration as `migration/<name>/<phase-file>.md`.
|
|
246
303
|
|
|
247
304
|
### Migration directory layout
|
|
@@ -250,14 +307,20 @@ Each `run` / `run-once` tick now checks for eligible migration work before falli
|
|
|
250
307
|
<live-migrations-dir>/
|
|
251
308
|
<migration-name>/
|
|
252
309
|
manifest.json # status, phases, wake-up schedule
|
|
310
|
+
.planning/
|
|
311
|
+
state.json # durable planning cursor and accepted step refs
|
|
312
|
+
stages/ # accepted planning stdout, suffixed on repeats
|
|
253
313
|
plan.md # the expanded plan
|
|
254
314
|
approaches/ # candidate approaches considered during planning
|
|
255
315
|
phase-1-<name>.md # per-phase specification
|
|
256
316
|
phase-2-<name>.md
|
|
257
317
|
...
|
|
318
|
+
__transactions__/ # internal staged publish state
|
|
258
319
|
__intentional_skips__/ # migrations rejected at final review
|
|
259
320
|
```
|
|
260
321
|
|
|
322
|
+
Do not edit `.planning/` or `__transactions__/` by hand. Use `migration doctor` when the shape looks wrong.
|
|
323
|
+
|
|
261
324
|
### Wake-up rules
|
|
262
325
|
|
|
263
326
|
Migrations don't run on every tick. The scheduler now separates **activity** from
|
|
@@ -291,7 +354,7 @@ Before executing a phase, a ready-check agent verifies that the current phase pr
|
|
|
291
354
|
|
|
292
355
|
- **ready: yes** — phase executes; on green tests, the phase is marked done, any prior deferral markers are cleared, and the migration advances immediately to the next phase.
|
|
293
356
|
- **ready: no** — manifest activity is bumped, a retry cooldown is started, and a future `wake_up_on` is recorded when needed; the tick moves on.
|
|
294
|
-
- **ready: unverifiable** — the migration is
|
|
357
|
+
- **ready: unverifiable** — the migration is marked `awaiting_human_review` and put on cooldown. Automated migration ticks skip migrations awaiting human review until review clears the flag. Use `migration list --awaiting-review` to find it and `migration review <slug-or-path> --with ... --model ...` to resolve it interactively.
|
|
295
358
|
|
|
296
359
|
Human-facing migration references use the relative phase spec path, for example `phase-2-failure-report.md`. The manifest cursor stores the phase `name`, not a numeric index.
|
|
297
360
|
|
|
@@ -9,6 +9,8 @@ Small, test-gated cleanup commits by an AI coding agent.
|
|
|
9
9
|
|
|
10
10
|
Think of it as a supervised janitor loop: the agent proposes a cleanup, your tests decide if it stays.
|
|
11
11
|
|
|
12
|
+
Here's [an article](https://artisincode.com/essays/how-i-use-unspent-tokens/) I wrote about it.
|
|
13
|
+
|
|
12
14
|
## Install
|
|
13
15
|
|
|
14
16
|
Try it without installing:
|
|
@@ -44,6 +46,10 @@ uv pip install -e .
|
|
|
44
46
|
|
|
45
47
|
That gives you the `continuous-refactoring` command.
|
|
46
48
|
|
|
49
|
+
The CLI itself can be installed without `uv`, but the default validation command
|
|
50
|
+
is `uv run pytest`. Pass `--validation-command pytest` or a project-specific
|
|
51
|
+
script when the target repo does not use `uv`.
|
|
52
|
+
|
|
47
53
|
Maintainers: see the [release checklist](https://github.com/bigH/continuous-refactoring/blob/main/docs/release.md).
|
|
48
54
|
|
|
49
55
|
## Fastest way to get one refactor
|
|
@@ -69,15 +75,18 @@ continuous-refactoring run \
|
|
|
69
75
|
--max-attempts 2
|
|
70
76
|
```
|
|
71
77
|
|
|
72
|
-
That
|
|
78
|
+
That runs up to 10 refactor actions, then stops sooner if the finite target file
|
|
79
|
+
runs out or the loop starts failing. Use `run --focus-on-live-migrations` when
|
|
80
|
+
you want the loop to work only on eligible live migrations; it bypasses target
|
|
81
|
+
selection and `--max-refactors`.
|
|
73
82
|
|
|
74
83
|
## What it does
|
|
75
84
|
|
|
76
|
-
- Resolves
|
|
85
|
+
- Resolves each source action from `--targets`, `--globs`, `--extensions`, or `--paths`, with optional natural-language scoping via `--scope-instruction`.
|
|
77
86
|
- Runs the agent with a refactoring prompt + your "taste" guidelines.
|
|
78
87
|
- Runs your validation command (default: `uv run pytest`).
|
|
79
88
|
- If green and there's a diff, it commits locally and leaves the branch for you to inspect.
|
|
80
|
-
- Repeats until it
|
|
89
|
+
- Repeats until it spends the action budget, exhausts a finite target file, hits the retry budget, or stacks too many failures.
|
|
81
90
|
|
|
82
91
|
## Requirements
|
|
83
92
|
|
|
@@ -96,8 +105,8 @@ continuous-refactoring init --in-repo-taste
|
|
|
96
105
|
|
|
97
106
|
# 2. (Optional) Write your refactoring taste — either edit the file, have an agent interview you,
|
|
98
107
|
# or refine an existing draft collaboratively
|
|
99
|
-
continuous-refactoring taste --interview --with codex --model gpt-5
|
|
100
|
-
continuous-refactoring taste --refine --with codex --model gpt-5
|
|
108
|
+
continuous-refactoring taste --interview --with codex --model gpt-5
|
|
109
|
+
continuous-refactoring taste --refine --with codex --model gpt-5
|
|
101
110
|
|
|
102
111
|
# 3. Do one pass
|
|
103
112
|
continuous-refactoring run-once \
|
|
@@ -113,17 +122,23 @@ continuous-refactoring run \
|
|
|
113
122
|
--sleep 5
|
|
114
123
|
```
|
|
115
124
|
|
|
125
|
+
Active taste agent modes require `--with` and `--model`; taste agent sessions
|
|
126
|
+
always run at fixed `medium` effort.
|
|
127
|
+
|
|
116
128
|
## Subcommands
|
|
117
129
|
|
|
118
130
|
| Command | What it does |
|
|
119
131
|
|---|---|
|
|
120
132
|
| `init` | Registers this directory as a project, creates a default `taste.md`, and can store `--live-migrations-dir` or `--in-repo-taste`. |
|
|
121
|
-
| `taste` | Prints the active taste file path. Add `--interview` to have an agent author it, `--refine` to iteratively improve an existing taste doc, `--upgrade` to refresh stale taste dimensions, `--global` for the shared file, and `--force` to let `--interview` overwrite custom content after writing a `.bak`. |
|
|
133
|
+
| `taste` | Prints the active taste file path. Add `--interview` to have an agent author it, `--refine` to iteratively improve an existing taste doc, `--upgrade` to refresh stale taste dimensions, `--global` for the shared file, and `--force` to let `--interview` overwrite custom content after writing a `.bak`. Active agent modes require `--with` and `--model`, then run at fixed `medium` effort. |
|
|
122
134
|
| `run-once` | Single pass on one resolved target. No retry. If there is a diff and validation passes, it commits locally and prints the diffstat. |
|
|
123
|
-
| `run` | The loop. Iterates
|
|
135
|
+
| `run` | The loop. Iterates refactor actions, retries on failure, and commits successful changes locally. Add `--focus-on-live-migrations` to bypass targeting and work only on eligible live migrations. |
|
|
124
136
|
| `upgrade` | Checks that the global config manifest is current, rewrites it idempotently, and warns if the global taste file is stale. |
|
|
125
|
-
| `
|
|
126
|
-
| `
|
|
137
|
+
| `migration list` | Lists visible migrations as TSV with headers. Add `--status <status>` or `--awaiting-review` to filter, or `--no-headers` for parsing. |
|
|
138
|
+
| `migration doctor <slug-or-path>` | Validates one visible migration's consistency. |
|
|
139
|
+
| `migration doctor --all` | Validates every visible migration plus internal transaction state. |
|
|
140
|
+
| `migration review <slug-or-path>` | Starts staged review for a migration awaiting human review. Requires `--with` and `--model`; review runs at fixed internal `high` effort. |
|
|
141
|
+
| `migration refine <slug-or-path>` | Records feedback for a planning or unexecuted ready migration and runs one staged planning revision. Requires `--message <text>` or `--file <path>`, plus `--with` and `--model`; refine runs at fixed internal `high` effort. Add `--show-agent-logs` to mirror the planning agent. |
|
|
127
142
|
|
|
128
143
|
## Targeting / Useful flags
|
|
129
144
|
|
|
@@ -134,29 +149,56 @@ Target resolution is first-match-wins:
|
|
|
134
149
|
|
|
135
150
|
These flags are not mutually exclusive, but only the highest-priority populated source is used.
|
|
136
151
|
|
|
137
|
-
- `--targets path/to/targets.jsonl` — explicit list; one JSON object per line with `description`, `files`, optional `scoping`, `model-override`, `effort-override`. Effort overrides use `low`, `medium`, `high`, or `xhigh`.
|
|
138
|
-
- `--globs 'src/**/*.py:tests/**/*.py'` — colon-separated globs
|
|
139
|
-
- `--extensions .py,.ts` — shorthand that expands to `**/*.py`, `**/*.ts`; each matched file
|
|
140
|
-
- `--paths a.py:b.py` — literal paths, all treated as one target.
|
|
141
|
-
- `--scope-instruction "clean up the auth module"` — extra free-text scoping. If file
|
|
152
|
+
- `--targets path/to/targets.jsonl` — explicit finite list; one JSON object per line with `description`, `files`, optional `scoping`, `model-override`, `effort-override`. Effort overrides use `low`, `medium`, `high`, or `xhigh`. If `--max-refactors` is omitted, `run` processes the file once and stops.
|
|
153
|
+
- `--globs 'src/**/*.py:tests/**/*.py'` — colon-separated globs matched once against tracked files from `git ls-files`; each refactor action samples one matched file, so files can repeat.
|
|
154
|
+
- `--extensions .py,.ts` — shorthand that expands to `**/*.py`, `**/*.ts` against tracked files from `git ls-files`; each refactor action samples one matched file, so files can repeat.
|
|
155
|
+
- `--paths a.py:b.py` — literal user-provided paths, all treated as one grouped target; each refactor action reuses that group.
|
|
156
|
+
- `--scope-instruction "clean up the auth module"` — extra free-text scoping. If selected file patterns resolve nothing, this becomes the useful fallback context.
|
|
142
157
|
|
|
143
|
-
If
|
|
158
|
+
If `--globs` or `--extensions` match no tracked files and there is no
|
|
159
|
+
`--scope-instruction`, `run` completes successfully with zero refactor actions;
|
|
160
|
+
`run-once` falls back to a no-file `general refactoring` target. `--paths` is
|
|
161
|
+
literal input and is not filtered through `git ls-files`.
|
|
162
|
+
|
|
163
|
+
If you provide none of `--targets`, `--globs`, `--extensions`, or `--paths`,
|
|
164
|
+
then `run` and `run-once` require `--scope-instruction`; the driver still
|
|
165
|
+
random-samples tracked files from `git ls-files` for each action and uses the
|
|
166
|
+
scope text as context for that target.
|
|
144
167
|
|
|
145
168
|
### Migrations & taste flags
|
|
146
169
|
|
|
147
170
|
- `init --live-migrations-dir PATH` — enables the larger-refactoring workflow for this project. The path is stored repo-relative in the project registry and created if missing.
|
|
148
171
|
- `init --in-repo-taste [PATH]` — stores this project's taste file in the repo and remembers the repo-relative path. Defaults to `.continuous-refactoring/taste.md`; re-run `init --in-repo-taste ...` to choose a different path.
|
|
149
|
-
- `
|
|
150
|
-
- `
|
|
172
|
+
- `migration list` — shows visible migrations as TSV with headers; `--awaiting-review` narrows to human-review handoffs and `--no-headers` keeps parser-friendly rows only.
|
|
173
|
+
- `migration doctor <slug-or-path>` / `migration doctor --all` — read-only consistency checks. Doctor reports problems; it does not repair them.
|
|
174
|
+
- `migration review <slug-or-path> --with ... --model ...` — resolves an `awaiting_human_review` migration through a staged workspace at fixed internal `high` effort.
|
|
175
|
+
- `migration refine <slug-or-path> (--message <text>|--file <path>) --with ... --model ... [--show-agent-logs]` — adds user feedback to a planning or unexecuted ready migration and resumes planning through the `revise` step when reopening ready work at fixed internal `high` effort.
|
|
176
|
+
- `taste --refine --with ... --model ...` — opens a collaborative editing session for the taste file. The agent keeps refining until you tell it to write, then the session ends automatically after the settled write.
|
|
177
|
+
- `taste --upgrade --with ... --model ...` — re-interviews for taste dimensions added since your last version. No-op when already current; use `taste --refine` if you want to rework the doc anyway.
|
|
178
|
+
- Taste agent sessions always use fixed `medium` effort.
|
|
151
179
|
- `taste --force` — only applies to `--interview`; it allows a customized taste file to be overwritten after backing it up to `taste.md.bak`.
|
|
152
180
|
|
|
181
|
+
Canonical migration commands:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
continuous-refactoring migration list
|
|
185
|
+
continuous-refactoring migration list --status planning
|
|
186
|
+
continuous-refactoring migration list --awaiting-review
|
|
187
|
+
continuous-refactoring migration list --no-headers
|
|
188
|
+
continuous-refactoring migration doctor <slug-or-path>
|
|
189
|
+
continuous-refactoring migration doctor --all
|
|
190
|
+
continuous-refactoring migration review <slug-or-path> --with codex --model gpt-5
|
|
191
|
+
continuous-refactoring migration refine <slug-or-path> --message "split the risky phase" --with codex --model gpt-5
|
|
192
|
+
continuous-refactoring migration refine <slug-or-path> --file feedback.md --with codex --model gpt-5
|
|
193
|
+
```
|
|
194
|
+
|
|
153
195
|
### Shared `run` / `run-once` flags
|
|
154
196
|
|
|
155
197
|
- `--with`, `--model` — required agent backend/model selection.
|
|
156
198
|
- `--default-effort` — default effort for run calls. Defaults to `low`. Valid labels are `low`, `medium`, `high`, `xhigh`.
|
|
157
199
|
- `--max-allowed-effort` — cap for target overrides and migration escalation. Defaults to `xhigh`.
|
|
158
200
|
- `--repo-root PATH` — repository root; defaults to the current directory.
|
|
159
|
-
- `--validation-command` — defaults to `uv run pytest`.
|
|
201
|
+
- `--validation-command` — defaults to `uv run pytest`. This is parsed with `shlex.split` and run without a shell, so simple commands like `pytest -q` work, but shell syntax such as `cmd && cmd`, pipes, redirects, or leading `VAR=value` assignments is not interpreted. Put compound validation in a script.
|
|
160
202
|
- `--timeout` — per-agent-call timeout in seconds.
|
|
161
203
|
- `--show-agent-logs` / `--show-command-logs` — mirror output to your terminal instead of just logging.
|
|
162
204
|
- `--refactoring-prompt` — override the default refactoring prompt.
|
|
@@ -164,10 +206,11 @@ If you provide none of `--targets`, `--globs`, `--extensions`, or `--paths`, the
|
|
|
164
206
|
|
|
165
207
|
### `run`-only flags
|
|
166
208
|
|
|
167
|
-
- `--max-attempts N` — per-
|
|
168
|
-
- `--max-refactors N` — cap the number of
|
|
169
|
-
- `--
|
|
170
|
-
- `--
|
|
209
|
+
- `--max-attempts N` — per-action retry budget. `1` = no retry, `0` = unlimited (which means permanently broken actions will never give up).
|
|
210
|
+
- `--max-refactors N` — cap the number of refactor actions per run. Required unless you use `--targets` or `--focus-on-live-migrations`.
|
|
211
|
+
- `--focus-on-live-migrations` — bypass target selection and `--max-refactors`; iterate eligible live migrations until they are done, deferred, blocked, or the failure budget trips.
|
|
212
|
+
- `--max-consecutive-failures N` — bail after N actions fail in a row. Default 3.
|
|
213
|
+
- `--sleep SECONDS` — pause between completed actions. Useful when you want a long batch without hammering the repo or your agent budget.
|
|
171
214
|
- `--commit-message-prefix TEXT` — subject prefix for successful refactor or migration-plan commits. Default `continuous refactor`.
|
|
172
215
|
|
|
173
216
|
## Safety behaviors
|
|
@@ -184,13 +227,27 @@ If you provide none of `--targets`, `--globs`, `--extensions`, or `--paths`, the
|
|
|
184
227
|
Each run writes to `$TMPDIR/continuous-refactoring/<run-id>/`:
|
|
185
228
|
|
|
186
229
|
- `summary.json` — rolling status, counts, per-attempt stats
|
|
187
|
-
- `events.jsonl` — structured event log
|
|
230
|
+
- `events.jsonl` — structured event log with call roles such as
|
|
231
|
+
`scope-expansion`, `classify`, `planning.<step>`, `planning.publish`,
|
|
232
|
+
`phase.ready-check`, `phase.execute`, and `phase.validation`
|
|
188
233
|
- `run.log` — human-readable log
|
|
189
234
|
- `attempt-NNN/[retry-NN/]refactor/` — per-attempt agent + test stdout/stderr
|
|
235
|
+
- `baseline/initial/` — baseline validation stdout/stderr before work starts
|
|
236
|
+
- `classify/` — classifier agent stdout/stderr
|
|
237
|
+
- `scope-expansion/` — scope candidates, selection, and bypass reason
|
|
238
|
+
- `attempt-NNN/[retry-NN/]planning/<step>/` — planning agent stdout/stderr for
|
|
239
|
+
migration planning steps
|
|
240
|
+
- `phase-ready-check/` — phase precondition agent stdout/stderr
|
|
241
|
+
- `attempt-NNN/[retry-NN/]phase-execute/` — phase agent and validation logs
|
|
242
|
+
- `migration-probes/action-NNN/` — migration probe logs during normal `run`
|
|
243
|
+
actions, including planning, phase ready-checks, and phase execution
|
|
190
244
|
|
|
191
245
|
Mixed-effort runs are auditable: summaries and call events record the default effort, max allowed effort, requested effort, effective effort, source, and whether the request was capped.
|
|
192
246
|
|
|
193
|
-
The path prints at startup. Grep it when something goes sideways.
|
|
247
|
+
The path prints at startup. Grep it when something goes sideways. Failed
|
|
248
|
+
non-commit decisions also write durable XDG snapshots under the project failure
|
|
249
|
+
directory, usually
|
|
250
|
+
`~/.local/share/continuous-refactoring/projects/<uuid>/failures/`.
|
|
194
251
|
|
|
195
252
|
## Taste files
|
|
196
253
|
|
|
@@ -199,7 +256,7 @@ The taste file is a short bullet list of your refactoring preferences. It gets i
|
|
|
199
256
|
- Project taste: `~/.local/share/continuous-refactoring/projects/<uuid>/taste.md`, or the repo-local path chosen with `init --in-repo-taste [PATH]`
|
|
200
257
|
- Global taste: `~/.local/share/continuous-refactoring/global/taste.md`
|
|
201
258
|
|
|
202
|
-
Project taste wins over global. Use `taste` to print the active path, `taste --interview
|
|
259
|
+
Project taste wins over global. Use `taste` to print the active path, `taste --interview --with ... --model ...` to bootstrap one, `taste --refine --with ... --model ...` to rework it with an agent, or edit the file directly any time.
|
|
203
260
|
|
|
204
261
|
## Larger refactorings
|
|
205
262
|
|
|
@@ -218,7 +275,7 @@ This tells the CLI where to store migration artifacts. The path is repo-relative
|
|
|
218
275
|
Each `run` / `run-once` tick now checks for eligible migration work before falling back to single-commit cleanups:
|
|
219
276
|
|
|
220
277
|
1. **Classify** — a classifier agent reads the target and decides: `cohesive-cleanup` (one-shot path) or `needs-plan` (migration path).
|
|
221
|
-
2. **Plan** — for `needs-plan` targets,
|
|
278
|
+
2. **Plan** — for `needs-plan` targets, each automation action runs exactly one planning step: approaches, pick-best, expand, review, optional revise/review-2, then final-review. Accepted steps update `.planning/state.json`, store stdout under `.planning/stages/`, and publish through a staged transaction. Failed current-step output stays in run artifacts and is not resume input.
|
|
222
279
|
3. **Execute** — each phase is a self-contained unit of work. The tick picks the oldest eligible migration, checks whether its current phase precondition is satisfied, and executes it on the current branch. Phase completion is judged against the phase file's `## Definition of Done`; commit message identifies the migration as `migration/<name>/<phase-file>.md`.
|
|
223
280
|
|
|
224
281
|
### Migration directory layout
|
|
@@ -227,14 +284,20 @@ Each `run` / `run-once` tick now checks for eligible migration work before falli
|
|
|
227
284
|
<live-migrations-dir>/
|
|
228
285
|
<migration-name>/
|
|
229
286
|
manifest.json # status, phases, wake-up schedule
|
|
287
|
+
.planning/
|
|
288
|
+
state.json # durable planning cursor and accepted step refs
|
|
289
|
+
stages/ # accepted planning stdout, suffixed on repeats
|
|
230
290
|
plan.md # the expanded plan
|
|
231
291
|
approaches/ # candidate approaches considered during planning
|
|
232
292
|
phase-1-<name>.md # per-phase specification
|
|
233
293
|
phase-2-<name>.md
|
|
234
294
|
...
|
|
295
|
+
__transactions__/ # internal staged publish state
|
|
235
296
|
__intentional_skips__/ # migrations rejected at final review
|
|
236
297
|
```
|
|
237
298
|
|
|
299
|
+
Do not edit `.planning/` or `__transactions__/` by hand. Use `migration doctor` when the shape looks wrong.
|
|
300
|
+
|
|
238
301
|
### Wake-up rules
|
|
239
302
|
|
|
240
303
|
Migrations don't run on every tick. The scheduler now separates **activity** from
|
|
@@ -268,7 +331,7 @@ Before executing a phase, a ready-check agent verifies that the current phase pr
|
|
|
268
331
|
|
|
269
332
|
- **ready: yes** — phase executes; on green tests, the phase is marked done, any prior deferral markers are cleared, and the migration advances immediately to the next phase.
|
|
270
333
|
- **ready: no** — manifest activity is bumped, a retry cooldown is started, and a future `wake_up_on` is recorded when needed; the tick moves on.
|
|
271
|
-
- **ready: unverifiable** — the migration is
|
|
334
|
+
- **ready: unverifiable** — the migration is marked `awaiting_human_review` and put on cooldown. Automated migration ticks skip migrations awaiting human review until review clears the flag. Use `migration list --awaiting-review` to find it and `migration review <slug-or-path> --with ... --model ...` to resolve it interactively.
|
|
272
335
|
|
|
273
336
|
Human-facing migration references use the relative phase spec path, for example `phase-2-failure-report.md`. The manifest cursor stores the phase `name`, not a numeric index.
|
|
274
337
|
|