@dpeek/codeless 0.1.1 → 0.1.3
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.
- package/README.md +79 -33
- package/extension/implementer-reporting.js +78 -10
- package/extension/planner.js +135 -15
- package/package.json +2 -1
- package/prompts/change.md +40 -0
- package/prompts/commit.md +37 -0
- package/prompts/implement.md +17 -0
- package/prompts/review.md +20 -0
- package/spec/workflow.md +215 -149
- package/src/attempt.ts +4 -1
- package/src/cli.ts +254 -71
- package/src/metrics.ts +90 -4
package/spec/workflow.md
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
# Codeless workflow
|
|
2
2
|
|
|
3
|
-
Codeless is an attended workflow for delivering independent capability changes
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
[the workflow todo](../todo/workflow.md).
|
|
3
|
+
Codeless is an attended workflow for delivering independent capability changes through a
|
|
4
|
+
project's integration branch. This contract owns the implemented workflow; the [project
|
|
5
|
+
guide](../README.md) explains installation, operation, and reusable execution mechanics.
|
|
6
|
+
Missing workflow behavior belongs in [the workflow todo](../todo/workflow.md).
|
|
8
7
|
|
|
9
|
-
##
|
|
8
|
+
## Ownership and lifecycle
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
Codeless owns reusable execution mechanics and shared local state. Projects own
|
|
11
|
+
directions, prompt contents, model choices, and approval/review policy. Pi and Herdr own
|
|
12
|
+
their runtime APIs and process behavior.
|
|
13
|
+
|
|
14
|
+
A stream has one lowercase kebab-case slug, one `stream/<slug>` branch and worktree, one
|
|
15
|
+
planner, one implementer pane, and at most one approved change in progress. Work inside
|
|
16
|
+
a stream is sequential:
|
|
14
17
|
|
|
15
18
|
1. create or reopen the stream from the configured integration branch;
|
|
16
19
|
2. propose one small change and wait for operator approval;
|
|
@@ -21,22 +24,42 @@ progress. Work inside a stream is sequential:
|
|
|
21
24
|
slot; and
|
|
22
25
|
6. replace the planner session before proposing another change.
|
|
23
26
|
|
|
24
|
-
Automated landing updates only the configured integration branch's dedicated
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
Automated landing updates only the configured integration branch's dedicated clean
|
|
28
|
+
checkout. Other branches and checkouts are neither stream sources nor landing targets.
|
|
29
|
+
Codeless does not push.
|
|
30
|
+
|
|
31
|
+
Each project supplies `.codeless/config.json`, a direction at `<directions>/<slug>.md`, and
|
|
32
|
+
`change`, `implement`, `review`, and `commit` prompt templates. Creation refuses a
|
|
33
|
+
missing direction or prompt and an existing stream. Opening requires the existing
|
|
34
|
+
branch, worktree, journal, proposal file, direction, and prompts. Both install
|
|
35
|
+
dependencies before starting a new planner. Reopening a running managed planner
|
|
36
|
+
only focuses its workspace and preserves its conversation.
|
|
37
|
+
|
|
38
|
+
## Command and tool boundaries
|
|
39
|
+
|
|
40
|
+
The executable currently exposes both operator commands and subprocess entrypoints used
|
|
41
|
+
by planner tools:
|
|
42
|
+
|
|
43
|
+
| Surface | Responsibility |
|
|
44
|
+
| ------------------------------------------------- | ----------------------------------------------------------------------------- |
|
|
45
|
+
| `init`, `create`, `open`, `metrics` | Operator setup, session management, and observation |
|
|
46
|
+
| `approve`, `dispatch`, `rework`, `finish`, `next` | Backing commands for the corresponding planner tools |
|
|
47
|
+
| `land` | Commit integration, invoked by the project prompt or operator during recovery |
|
|
48
|
+
| `/change`, `/implement`, `/review`, `/commit` | Project-owned prompt templates |
|
|
49
|
+
| `/streams-activate`, `/streams-next` | Package-owned planner activation and session replacement |
|
|
50
|
+
| `/codeless-rework`, `/codeless-finish` | Package-owned commands delivered to the existing implementer |
|
|
27
51
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
direction, and prompts. Both install dependencies before starting the planner.
|
|
52
|
+
The Pi commands bridge session/process operations. In particular, `next_stream_change`
|
|
53
|
+
queues a command so session replacement occurs after the current turn settles. Surface
|
|
54
|
+
reductions and additional tools belong in the workflow todo; all backing CLI commands
|
|
55
|
+
remain callable today.
|
|
33
56
|
|
|
34
57
|
## Shared local state
|
|
35
58
|
|
|
36
|
-
Codeless keeps workflow state outside tracked project documents in a shared
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
59
|
+
Codeless keeps workflow state outside tracked project documents in a shared workspace
|
|
60
|
+
selected by the local Git `codeless.workspaceRoot` setting or, by default, at
|
|
61
|
+
`.codeless/state/` in the primary checkout. The default directory is Git-ignored, and
|
|
62
|
+
every linked worktree resolves the same primary-checkout state:
|
|
40
63
|
|
|
41
64
|
```text
|
|
42
65
|
<primary-checkout>/.codeless/state/
|
|
@@ -49,169 +72,212 @@ Git-ignored, and every linked worktree resolves the same primary-checkout state:
|
|
|
49
72
|
metrics/<slug>/NNN.json
|
|
50
73
|
```
|
|
51
74
|
|
|
52
|
-
`codeless init` is the explicit, idempotent bootstrap for a configured project.
|
|
53
|
-
|
|
54
|
-
|
|
75
|
+
`codeless init` is the explicit, idempotent bootstrap for a configured project. It
|
|
76
|
+
requires the configured integration branch and creates missing copies of the four
|
|
77
|
+
package-owned generic prompt starters in the invoking checkout's configured in-project
|
|
78
|
+
prompt directory. It validates every template and destination before mutation, reports
|
|
79
|
+
each absolute path as created or preserved, and never replaces an existing prompt file.
|
|
80
|
+
A non-directory ancestor or non-file prompt collision stops without prompt, state, ignore,
|
|
81
|
+
or worktree mutation. Missing prompts are not generated when init is invoked from the
|
|
82
|
+
dedicated integration checkout; the operator must initialize from an editable checkout.
|
|
83
|
+
|
|
84
|
+
Init creates the shared state directories plus that branch's worktree only at
|
|
55
85
|
`<workspace>/worktree/<integration-branch>`. It reuses only the exact registered
|
|
56
|
-
canonical checkout. An occupied target, a branch registered elsewhere, invalid
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
contracts, and are never copied into `spec/`.
|
|
86
|
+
canonical checkout. An occupied target, a branch registered elsewhere, invalid checkout,
|
|
87
|
+
or ambiguous Git registration stops unchanged; init never switches branches, moves
|
|
88
|
+
worktrees, or repairs conflicts. With the default workspace, it accepts a repository
|
|
89
|
+
ignore rule only when it ignores the state path without covering configuration or
|
|
90
|
+
configured prompts, otherwise appending the narrow `/.codeless/state/` rule. An absolute
|
|
91
|
+
workspace never changes repository ignores. No other command bootstraps this layout.
|
|
92
|
+
|
|
93
|
+
`planner.md` owns decisions, approvals, review outcomes, landing history, and the
|
|
94
|
+
context needed by a fresh planner. `change.md` is the editable current proposal.
|
|
95
|
+
`changes/NNN.md` is the immutable-by-policy approved input to one implementation loop.
|
|
96
|
+
These documents are local workflow state, not product contracts, and are never copied
|
|
97
|
+
into `spec/`.
|
|
69
98
|
|
|
70
99
|
After operator `go`, the argument-free planner-only `approve_stream_change` tool
|
|
71
|
-
promotes the current proposal before any dispatch. It derives the active planner
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
the
|
|
78
|
-
`
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
100
|
+
promotes the current proposal before any dispatch. It derives the active planner session
|
|
101
|
+
and passes it to the backing CLI, which requires its `<slug>-planner` identity to match
|
|
102
|
+
the clean `stream/<slug>` worktree and branch. The stream commit established for
|
|
103
|
+
planning is the proposal's base; approval does not compare it with the moving
|
|
104
|
+
integration branch. Landing alone acquires the integration lock and rebases that
|
|
105
|
+
stream change when integration has advanced. The proposal needs one usable H1 title plus
|
|
106
|
+
the `Why`, `Change`, `Acceptance`, and
|
|
107
|
+
`Decisions` headings in that order; titles must be representable by the canonical
|
|
108
|
+
record. The CLI writes `changes/NNN.md` exclusively, where `NNN` is the successor of the
|
|
109
|
+
greatest existing three-digit number (and stops after `999`), then appends a canonical
|
|
110
|
+
journal approval containing the file, title, and proposal hash. Repeated calls reconcile
|
|
111
|
+
that exact file and entry, completing one missing step without another number;
|
|
112
|
+
conflicting or ambiguous partial state stops unchanged. Rejection and ordinary feedback
|
|
113
|
+
allocate nothing. Dispatch remains a separate explicit tool call using the returned
|
|
114
|
+
absolute path.
|
|
83
115
|
|
|
84
116
|
## Role sessions and configuration
|
|
85
117
|
|
|
86
118
|
Project configuration selects an exact Pi provider, model, and thinking level
|
|
87
119
|
independently for planner and implementer roles.
|
|
88
120
|
|
|
89
|
-
Before starting either role, Codeless uses Pi's machine-readable APIs to require
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
121
|
+
Before starting either role, Codeless uses Pi's machine-readable APIs to require the
|
|
122
|
+
configured model, authentication, supported thinking level, and effective selection. It
|
|
123
|
+
fails before agent work rather than accepting a fallback model or clamped thinking
|
|
124
|
+
level. The validated selection is displayed and passed to the role process.
|
|
125
|
+
|
|
126
|
+
Configuration changes take effect only at a new role-session boundary. An active review
|
|
127
|
+
or remediation keeps its implementer setting. A successful post-landing handoff rereads
|
|
128
|
+
and validates planner configuration from the fast-forwarded stream worktree before the
|
|
129
|
+
replacement session receives its first project prompt.
|
|
130
|
+
|
|
131
|
+
Every new planner process uses `herdr agent start`, which owns its managed name
|
|
132
|
+
and waits for interactive readiness before Codeless sends activation. `open`
|
|
133
|
+
reuses the stream workspace and its root planner pane, adding a right-hand shell
|
|
134
|
+
only when absent. It accepts only a lone planner pane or a planner with one
|
|
135
|
+
right-hand pane. Starting a planner requires both existing panes to be shells in
|
|
136
|
+
the stream worktree; occupied, mismatched, or ambiguous layouts stop unchanged.
|
|
137
|
+
The operator must invoke opening from outside those target panes. Reopening an
|
|
138
|
+
existing managed planner focuses it without installation or another prompt.
|
|
139
|
+
|
|
140
|
+
The package-owned extension activates creation, reopening, and post-landing
|
|
141
|
+
replacement. Before the first project prompt it requires the exact
|
|
142
|
+
`<slug>-planner` Pi name, `<slug-with-hyphens-replaced>_planner` Herdr name,
|
|
143
|
+
managed interactive readiness, matching foreground worktree, and the current
|
|
144
|
+
native Pi session ID/file reported by Herdr's official Pi lifecycle integration.
|
|
145
|
+
It verifies `approve_stream_change`, `dispatch_stream_implementer`,
|
|
146
|
+
`rework_stream_implementer`, `finish_stream_implementer`, and `next_stream_change`
|
|
147
|
+
are active. During replacement, an otherwise-valid previous native session
|
|
148
|
+
reference receives a brief bounded synchronization wait; a wrong name, process,
|
|
149
|
+
lifecycle source, or worktree fails immediately. Any binding that remains missing
|
|
150
|
+
or incompatible stops visibly before `/change`. Activation never repairs names.
|
|
151
|
+
The direct `planner` command is removed;
|
|
152
|
+
recovery exits Pi deliberately and reopens from another Herdr shell.
|
|
153
|
+
|
|
154
|
+
Pi session replacement keeps the managed process and Herdr name while changing
|
|
155
|
+
its native conversation reference. Codeless revalidates that new binding before
|
|
156
|
+
prompting the replacement. Implementers use the corresponding `_impl` and
|
|
157
|
+
`-impl` names. Codeless loads its own extension explicitly; Herdr's official Pi
|
|
158
|
+
integration supplies lifecycle and native-session reporting. This boundary was
|
|
159
|
+
verified against Herdr 0.8.2 and Pi 0.85.1.
|
|
113
160
|
|
|
114
161
|
## Dispatch and review
|
|
115
162
|
|
|
116
163
|
The planner-only `dispatch_stream_implementer` tool accepts an absolute approved
|
|
117
|
-
`changes/NNN.md` path. Dispatch verifies the stream branch, clean worktree,
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
164
|
+
`changes/NNN.md` path. Dispatch verifies the stream branch, clean worktree, planner
|
|
165
|
+
pane, prompts, and implementer selection. It creates or reuses the right-hand Herdr pane
|
|
166
|
+
only when that pane is an available shell or the expected idle implementer, starts a
|
|
167
|
+
fresh ephemeral Pi implementer in the stream worktree, submits `/implement`, and waits
|
|
168
|
+
for at most one hour.
|
|
122
169
|
|
|
123
170
|
Successful dispatch loads the package-owned reporting extension while retaining
|
|
124
|
-
`--no-session` and passes its report configuration through that extension's
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
and branch summaries), available Pi model cost estimate with USD currency and
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
per-change metric record,
|
|
136
|
-
conflicting duplicate ID. Missing, malformed, or unwritable collection warns
|
|
137
|
-
and yields an explicitly incomplete attempt when possible without failing or
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
The planner inspects the full diff and relevant code, checks the approved
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
171
|
+
`--no-session` and passes its report configuration through that extension's explicit Pi
|
|
172
|
+
string flag, then returns one normalized attempt to the planner tool before it queues
|
|
173
|
+
the expanded `/review` prompt. Attempts have a stable ID and capture only
|
|
174
|
+
stream/change/role, start and settlement timestamps, Pi's actual settled
|
|
175
|
+
provider/model/thinking selection, terminal outcome and final text, Pi
|
|
176
|
+
input/output/cache usage over the collected attempt (including tool results, compaction,
|
|
177
|
+
and branch summaries), available Pi model cost estimate with USD currency and source,
|
|
178
|
+
and tool/error counts. Cost is omitted when Pi did not supply valid cost totals.
|
|
179
|
+
Collection stores final assistant text and aggregate measurements, not a transcript or
|
|
180
|
+
separate prompt, source, credential, or thinking fields. Final assistant text is not
|
|
181
|
+
redacted. The extension writes its report atomically once, then remains disarmed for
|
|
182
|
+
remediation; Codeless atomically deduplicates it inside the per-change metric record,
|
|
183
|
+
rejecting a conflicting duplicate ID. Missing, malformed, or unwritable collection warns
|
|
184
|
+
and yields an explicitly incomplete attempt when possible without failing or repeating a
|
|
185
|
+
settled implementation.
|
|
186
|
+
|
|
187
|
+
The planner inspects the full diff and relevant code, checks the approved acceptance
|
|
188
|
+
criteria, and runs focused checks when the implementation output is insufficient. The
|
|
189
|
+
planner-only `rework_stream_implementer` tool accepts that approved path and concise
|
|
190
|
+
feedback, verifies the expected idle implementer, its right-hand pane and worktree, then
|
|
191
|
+
invokes one package-owned Pi command. That command verifies the immutable startup
|
|
192
|
+
stream/change scope, arms package reporting in the existing conversation, and submits
|
|
193
|
+
one bounded feedback turn. It records usage from that remediation turn, excluding
|
|
194
|
+
earlier conversation entries, and returns one `rework` attempt before queueing review
|
|
195
|
+
again; missing or malformed reports warn and yield an incomplete attempt after
|
|
196
|
+
settlement. Prompt rejection, timeout, blocked state, identity/worktree/change mismatch,
|
|
197
|
+
or ambiguous pane stops without a completed attempt or queued review. The separate
|
|
198
|
+
planner-only `finish_stream_implementer` tool first verifies that immutable
|
|
199
|
+
stream/change scope in the same idle implementer, then gracefully exits it and waits for
|
|
200
|
+
its pane to become the stream-worktree shell. Its failure stops before commit or landing
|
|
201
|
+
instructions continue.
|
|
202
|
+
|
|
203
|
+
Dispatch, remediation, and shutdown do not retry automatically or replace an implementer
|
|
204
|
+
session or its selected model.
|
|
149
205
|
|
|
150
206
|
## Commit and landing
|
|
151
207
|
|
|
152
|
-
A reviewed change produces exactly one commit outside the merge base with the
|
|
153
|
-
|
|
154
|
-
then atomically acquires the shared `.land-lock` with its owner and captured
|
|
208
|
+
A reviewed change produces exactly one commit outside the merge base with the configured
|
|
209
|
+
integration branch. `codeless land <slug>` requires clean stream and integration
|
|
210
|
+
worktrees, then atomically acquires the shared `.land-lock` with its owner and captured
|
|
155
211
|
integration commit.
|
|
156
212
|
|
|
157
|
-
If the integration branch advanced, landing rebases the single stream commit. It then
|
|
158
|
-
runs the configured project check in the stream worktree, requires checks to
|
|
159
|
-
leave the worktree clean, and fast-forwards the dedicated
|
|
213
|
+
If the integration branch advanced, landing rebases the single stream commit. It then
|
|
214
|
+
rereads and runs the configured project check in the stream worktree, requires checks to
|
|
215
|
+
leave the worktree clean, and fast-forwards the dedicated integration checkout. Only
|
|
160
216
|
successful completion releases the lock.
|
|
161
217
|
|
|
162
|
-
A lock owned by another stream stops landing without polling. A rebase conflict,
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
218
|
+
A lock owned by another stream stops landing without polling. A rebase conflict, failed
|
|
219
|
+
check, or other error after acquisition retains this stream's lock for deliberate
|
|
220
|
+
recovery. Rerunning landing for the same owner is allowed only while the recorded
|
|
221
|
+
integration commit still matches. Codeless never removes a stale or ambiguous lock
|
|
222
|
+
automatically.
|
|
167
223
|
|
|
168
224
|
## Fresh planner handoff
|
|
169
225
|
|
|
170
226
|
After landing, the planner records the full landed commit hash and calls the
|
|
171
|
-
planner-only `next_stream_change` tool exactly once. The handoff requires the
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
Codeless captures the current integration branch, fast-forwards the stream worktree,
|
|
177
|
-
the updated direction, prompts, and planner selection, and returns the next
|
|
178
|
-
session name and `/change` prompt. The extension replaces the Pi session in the
|
|
179
|
-
|
|
180
|
-
|
|
227
|
+
planner-only `next_stream_change` tool exactly once. The handoff requires the latest
|
|
228
|
+
numbered change, the full landed commit hash in the journal and stream history, no unlanded stream
|
|
229
|
+
commit, a clean worktree, and no unresolved lock owned by this stream or by an unknown
|
|
230
|
+
owner.
|
|
231
|
+
|
|
232
|
+
Codeless captures the current integration branch, fast-forwards the stream worktree,
|
|
233
|
+
validates the updated direction, prompts, and planner selection, and returns the next
|
|
234
|
+
session name and `/change` prompt. The extension replaces the Pi session in the same
|
|
235
|
+
pane, preserves its name, activates the validated selection and planner identity, and
|
|
236
|
+
only then sends the project prompt. Conversation history is not copied; the journal and
|
|
181
237
|
project files carry durable context.
|
|
182
238
|
|
|
183
239
|
A cancelled or failed replacement stops for operator attention. Landing remains
|
|
184
|
-
complete, and any successful preparation fast-forward remains applied. There is
|
|
185
|
-
|
|
186
|
-
|
|
240
|
+
complete, and any successful preparation fast-forward remains applied. There is no
|
|
241
|
+
background retry. The replacement planner still needs a new operator `go` before another
|
|
242
|
+
implementation.
|
|
187
243
|
|
|
188
244
|
## Local workflow metrics
|
|
189
245
|
|
|
190
|
-
The first dispatch for a stream and numbered change creates one atomic local
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
`codeless metrics` reports every recorded stream and a project total
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
246
|
+
The first dispatch for a stream and numbered change creates one atomic local metric
|
|
247
|
+
record. Every accepted dispatch creates a new attempt ID; re-ingesting an attempt ID is
|
|
248
|
+
atomic and idempotent, while the original dispatch timestamp stays unchanged. Successful
|
|
249
|
+
landing adds its timestamp and commit, or creates a landed record with unavailable
|
|
250
|
+
elapsed time when dispatch collection was unavailable. Collection warnings do not change
|
|
251
|
+
dispatch or landing outcomes.
|
|
252
|
+
|
|
253
|
+
`codeless metrics` reports every recorded stream and a project total in two tables. The
|
|
254
|
+
elapsed table reports landed and dispatched-but-unlanded change counts, measured versus
|
|
255
|
+
unavailable elapsed coverage, and total and average dispatch-to-land wall-clock time.
|
|
256
|
+
The attempt table aggregates only validated canonical attempt records and reports
|
|
257
|
+
distinct changes with rework, initial and rework turns, incomplete collection, exact
|
|
258
|
+
stored terminal-outcome labels, and summed tool errors.
|
|
259
|
+
|
|
260
|
+
Usage coverage is measured versus unavailable attempts; input, output, cache-read, and
|
|
261
|
+
cache-write totals include only attempts with recorded usage. Cost coverage follows the
|
|
262
|
+
same rule, and totals are grouped by recorded currency without conversion. Missing usage
|
|
263
|
+
or cost is unavailable, never zero. These measurements do not establish implementation
|
|
264
|
+
quality or review success. They are prospective local observations, not journal state,
|
|
265
|
+
an approval source, or a recovery mechanism.
|
|
207
266
|
|
|
208
267
|
## Limits
|
|
209
268
|
|
|
210
|
-
Codeless is attended and intentionally has no supervisor, project registry,
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
269
|
+
Codeless is attended and intentionally has no supervisor, project registry, queue,
|
|
270
|
+
automatic landing retry, stale-lock recovery, or unattended approval. Planner startup
|
|
271
|
+
reads every numbered change, and conflict recovery currently causes the configured
|
|
272
|
+
landing check to run twice. Because the default state is ignored, `git clean -fdx` can
|
|
273
|
+
delete it.
|
|
274
|
+
|
|
275
|
+
The single-active-change rule and the requirement to dispatch only approved input still
|
|
276
|
+
partly depend on planner instructions. Approval reconciles records and hashes but does
|
|
277
|
+
not require the previous approved change to be complete before allocating a different
|
|
278
|
+
proposal. Dispatch requires an existing numbered file, but does not validate its
|
|
279
|
+
approval record/hash or require it to be the latest change. These are implementation
|
|
280
|
+
gaps, not additional permissions.
|
|
215
281
|
|
|
216
282
|
## References
|
|
217
283
|
|
package/src/attempt.ts
CHANGED
|
@@ -3,6 +3,7 @@ export type Attempt = {
|
|
|
3
3
|
stream: string;
|
|
4
4
|
change: string;
|
|
5
5
|
role: "implementer";
|
|
6
|
+
kind: "initial" | "rework";
|
|
6
7
|
startedAt: string;
|
|
7
8
|
endedAt: string;
|
|
8
9
|
selection?: { provider: string; model: string; thinking: string };
|
|
@@ -23,6 +24,7 @@ export function validAttempt(value: unknown, stream: string, change: string): va
|
|
|
23
24
|
"stream",
|
|
24
25
|
"change",
|
|
25
26
|
"role",
|
|
27
|
+
"kind",
|
|
26
28
|
"startedAt",
|
|
27
29
|
"endedAt",
|
|
28
30
|
"selection",
|
|
@@ -34,7 +36,7 @@ export function validAttempt(value: unknown, stream: string, change: string): va
|
|
|
34
36
|
"errorCount",
|
|
35
37
|
"incomplete",
|
|
36
38
|
]);
|
|
37
|
-
const strings = ["id", "stream", "change", "role", "startedAt", "endedAt", "outcome"];
|
|
39
|
+
const strings = ["id", "stream", "change", "role", "kind", "startedAt", "endedAt", "outcome"];
|
|
38
40
|
if (
|
|
39
41
|
!Object.keys(attempt).every((key) => allowed.has(key)) ||
|
|
40
42
|
!strings.every((key) => typeof attempt[key] === "string" && attempt[key].length > 0) ||
|
|
@@ -43,6 +45,7 @@ export function validAttempt(value: unknown, stream: string, change: string): va
|
|
|
43
45
|
attempt["stream"] !== stream ||
|
|
44
46
|
attempt["change"] !== change ||
|
|
45
47
|
attempt["role"] !== "implementer" ||
|
|
48
|
+
!["initial", "rework"].includes(attempt["kind"] as string) ||
|
|
46
49
|
!Number.isSafeInteger(attempt["toolCalls"]) ||
|
|
47
50
|
(attempt["toolCalls"] as number) < 0 ||
|
|
48
51
|
!Number.isSafeInteger(attempt["errorCount"]) ||
|