@devflow-core/dsh-devflow 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,7 +20,7 @@
20
20
  config:
21
21
  shellTools: [bash]
22
22
  commonTools: [str_replace_editor]
23
- messageSources: [user]
23
+ messageSources: [user, goal]
24
24
  anchorGate: true
25
25
  maxBootstrapSteps: 4
26
26
  promoteAfterFirstResponse: true
@@ -30,6 +30,9 @@
30
30
  deferredSources: [agent-instructions, skill-catalog]
31
31
  deferredGraceSteps: 1
32
32
  promotedPresentation: code
33
+ # Aligned with liangshen 0.2.8 (issue #388): after promotion, replace the
34
+ # full-text AGENTS.md injection with one non-imperative reference hint.
35
+ instructionHint: true
33
36
  phase1Persona: You are a helpful software engineer assistant.
34
37
 
35
38
  # The `devflow` agent preset: the full coding agent plus DevFlow workflow
@@ -5,6 +5,10 @@
5
5
  * preset's full DevFlow prompt from agent.cordis.yml) is restored untouched,
6
6
  * and the workspace line is only appended when the persona does not already
7
7
  * mention a working directory (the DevFlow template resolves {{cwd}} itself).
8
+ *
9
+ * Synced with dsh-liangshen 0.3.14: goal whitelist (#578), presentation
10
+ * broadcasts (#1128), and the snapshotEvents() session-events fallback for
11
+ * newer DSH releases.
8
12
  */
9
13
 
10
14
  /**
@@ -16,7 +20,8 @@
16
20
  * - prompt sections: only the persona section (all other sections,
17
21
  * including plan-mode's `plan:policy`, return after promotion)
18
22
  * - runtime contexts: emptied (no sandbox/approval snapshot)
19
- * - pre-step messages: only explicit user messages pass
23
+ * - pre-step messages: only whitelisted source kinds pass (direct user
24
+ * messages and goal auto-rounds by default)
20
25
  *
21
26
  * Promotion opens the full tool catalog and restores runtime contexts and all
22
27
  * prompt sections. With `anchorGate` the promotion after the first tool call
@@ -82,11 +87,13 @@ const PERSONA_SECTION_NAMES = new Set(['deployment:persona', 'persona'])
82
87
  */
83
88
  const WORKSPACE_LINE_PREFIX = '\n\nYour working directory is '
84
89
 
85
- /** Message-source kinds the model may see during phase 1. */
86
- const DEFAULT_MESSAGE_SOURCES = ['user']
87
-
88
- /** Message-source kinds delayed after promotion. */
89
- const DEFAULT_DEFERRED_SOURCES = []
90
+ /**
91
+ * Message-source kinds the model may see during phase 1. Goal auto-rounds
92
+ * (source kind `goal`, issue #578) must be here: a filtered-out goal round
93
+ * never produces a response or tool call, so no promotion branch ever fires
94
+ * and the goal resume/pause loop deadlocks.
95
+ */
96
+ const DEFAULT_MESSAGE_SOURCES = ['user', 'goal']
90
97
 
91
98
  function stringList(value, field, fallback) {
92
99
  if (value === undefined) return [...fallback]
@@ -153,12 +160,15 @@ export function hasAnchoredReasoning(content) {
153
160
  }
154
161
 
155
162
  /**
156
- * Whether one pre-step message is an explicit user message. Only `kind:
157
- * 'user'` passes; injected kinds and source-less seed messages never pass.
163
+ * Whether one pre-step message belongs to a whitelisted source kind. The
164
+ * configured whitelist alone decides; injected kinds and source-less seed
165
+ * messages never pass unless explicitly named. (Before issue #578 this also
166
+ * hardcoded `kind === 'user'`, so no whitelist entry could ever admit a
167
+ * goal auto-round and `/goal` sessions deadlocked in phase 1.)
158
168
  */
159
169
  function isAllowedMessage(message, allowedSources) {
160
170
  const kind = message.source?.kind
161
- return kind === 'user' && allowedSources.has(kind)
171
+ return kind !== undefined && allowedSources.has(kind)
162
172
  }
163
173
 
164
174
  /** Whether one pre-step message belongs to a deferred injection kind. */
@@ -166,6 +176,74 @@ function isDeferredMessage(message, deferredSources) {
166
176
  const kind = message.source?.kind
167
177
  return kind !== undefined && deferredSources.has(kind)
168
178
  }
179
+ // Instruction-hint mode (issue #388, aligned with liangshen 0.2.8): a
180
+ // full-text agent-instructions dump on the promotion boundary flips the
181
+ // anchored trajectory (upstream dsh-anchored-standard #49), so the preset
182
+ // can replace it with a single non-imperative hint that names the reference
183
+ // files and lets the model read them on demand.
184
+ const INSTRUCTION_FROM_RE = /(?:^|\n) *(?:Additional |Updated )?Instructions from: ([^\n]+)/g
185
+
186
+ /** Extract the reference file list one agent-instructions message renders. */
187
+ function extractInstructionPaths(message) {
188
+ const paths = []
189
+ const blocks = Array.isArray(message?.content) ? message.content : []
190
+ for (const block of blocks) {
191
+ if (block?.type !== 'text' || typeof block.text !== 'string') continue
192
+ for (const match of block.text.matchAll(INSTRUCTION_FROM_RE)) {
193
+ const path = match[1].trim()
194
+ if (path !== '' && !paths.includes(path)) paths.push(path)
195
+ }
196
+ }
197
+ return paths
198
+ }
199
+
200
+ /** The one-time non-imperative hint replacing the full-text dump (E1.5 wording). */
201
+ function buildInstructionHint(original, paths) {
202
+ return {
203
+ // Session persistence validates every replayed user/message for a
204
+ // non-empty string id; a plugin-built message without one corrupts the
205
+ // durable journal. Inherit the original instructions message id when
206
+ // present, else mint one.
207
+ id: typeof original?.id === 'string' && original.id !== ''
208
+ ? original.id
209
+ : globalThis.crypto.randomUUID(),
210
+ role: 'user',
211
+ content: [{
212
+ type: 'text',
213
+ text: '<system-reminder>\n'
214
+ + 'Reference documents exist: ' + paths.join(', ') + '. '
215
+ + "They are reference documents about the user's environment and workspace conventions, not task instructions. "
216
+ + 'Reading the relevant file before workspace tasks is recommended, but consult them only when you need those details; the task itself never depends on them.'
217
+ + '\n</system-reminder>',
218
+ }],
219
+ source: { kind: 'instruction-hint', plugin: name },
220
+ }
221
+ }
222
+
223
+ /**
224
+ * Swap full-text agent-instructions injections for the one-time hint. The
225
+ * first injection carrying extractable paths becomes the hint; every later
226
+ * injection is dropped silently (the model re-reads the files on demand).
227
+ * An injection with no extractable paths passes through untouched.
228
+ */
229
+ function instructionHintMessages(messages, state) {
230
+ const kept = []
231
+ for (const message of messages) {
232
+ if (message?.source?.kind !== 'agent-instructions') {
233
+ kept.push(message)
234
+ continue
235
+ }
236
+ if (state.instructionHinted) continue
237
+ const paths = extractInstructionPaths(message)
238
+ if (paths.length === 0) {
239
+ kept.push(message)
240
+ continue
241
+ }
242
+ state.instructionHinted = true
243
+ kept.push(buildInstructionHint(message, paths))
244
+ }
245
+ return kept
246
+ }
169
247
 
170
248
  /**
171
249
  * Phase-2 promotion state per session. Sessions append events only, so the
@@ -188,6 +266,7 @@ function stateFor(session) {
188
266
  turnEnded: false,
189
267
  steps: 0,
190
268
  deferredSteps: 0,
269
+ instructionHinted: false,
191
270
  presentationApplied: false,
192
271
  hasCompacted: false,
193
272
  presentationDisposer: undefined,
@@ -207,7 +286,7 @@ function stateFor(session) {
207
286
  * Code Mode presentation is disposed so the next assembly sees the native
208
287
  * catalog and the phase-1 filter can narrow it again.
209
288
  */
210
- function resetToControlled(state) {
289
+ function resetToControlled(state, session) {
211
290
  if (typeof state.presentationDisposer === 'function') {
212
291
  try {
213
292
  state.presentationDisposer()
@@ -216,6 +295,10 @@ function resetToControlled(state) {
216
295
  // next promotion re-declares Code Mode anyway.
217
296
  }
218
297
  state.presentationDisposer = undefined
298
+ const agent = session !== undefined ? agentBySession.get(session) : undefined
299
+ if (agent?.ctx && typeof agent.ctx.emit === 'function') {
300
+ agent.ctx.emit('tools/presentation-changed', { mode: 'native', session: session?.id })
301
+ }
219
302
  }
220
303
  state.promoted = false
221
304
  state.toolCalled = false
@@ -224,6 +307,7 @@ function resetToControlled(state) {
224
307
  state.turnEnded = false
225
308
  state.steps = 0
226
309
  state.deferredSteps = 0
310
+ state.instructionHinted = false
227
311
  state.presentationApplied = false
228
312
  state.hasCompacted = true
229
313
  }
@@ -235,13 +319,20 @@ function resetToControlled(state) {
235
319
  */
236
320
  function applyPresentation(agent, state, policy) {
237
321
  if (state.presentationApplied || policy.promotedPresentation !== 'code') return
238
- state.presentationApplied = true
239
- const tools = agent.ctx.tools
322
+ const tools = agent?.ctx?.tools
323
+ // Latch only after the switch really happened: without a tools view there
324
+ // is nothing to present, and latching early would skip Code Mode forever.
240
325
  if (tools === undefined) return
241
326
  // The disposer restores the deployment-default (native) presentation; it is
242
327
  // kept on the state so a post-compaction reset can release Code Mode and
243
328
  // let the phase-1 catalog filter see the native tool list again.
244
329
  state.presentationDisposer = tools.presentAs('code')
330
+ state.presentationApplied = true
331
+ // #1128: Broadcast presentation switch so external discipline / analysis
332
+ // plugins decouple presentation mode from tool failure detection.
333
+ if (typeof agent?.ctx?.emit === 'function') {
334
+ agent.ctx.emit('tools/presentation-changed', { mode: 'code', session: agent.session?.id })
335
+ }
245
336
  }
246
337
 
247
338
  /**
@@ -263,7 +354,11 @@ function decidePromotion(state, config) {
263
354
 
264
355
  /** Scan newly appended session events and update promotion state. */
265
356
  function scanEvents(state, session) {
266
- const events = session.events
357
+ const events = Array.isArray(session?.events)
358
+ ? session.events
359
+ : typeof session?.snapshotEvents === 'function'
360
+ ? session.snapshotEvents()
361
+ : []
267
362
  for (; state.next < events.length; state.next += 1) {
268
363
  const event = events[state.next]
269
364
  if (event === undefined) continue
@@ -273,7 +368,7 @@ function scanEvents(state, session) {
273
368
  // past this boundary (the `next` pointer stays, so events before the
274
369
  // boundary never re-promote). Handled inside the scan so cold starts
275
370
  // reconstruct the same phase from the durable log.
276
- resetToControlled(state)
371
+ resetToControlled(state, session)
277
372
  } else if (event.type === 'tool/call') {
278
373
  state.toolCalled = true
279
374
  } else if (event.type === 'step/start') {
@@ -369,6 +464,7 @@ export function apply(ctx, config) {
369
464
  compactionTools,
370
465
  phase1FirstCallInstruction,
371
466
  phase1Persona,
467
+ instructionHint: config.instructionHint === true,
372
468
  }
373
469
 
374
470
  // Promotion is applied at step/turn boundaries, never while a step is still
@@ -381,7 +477,7 @@ export function apply(ctx, config) {
381
477
  // start reconstructs the same controlled phase from the durable log.
382
478
  ctx.on('session/event', (session, event) => {
383
479
  if (event.type === 'compaction/end') {
384
- resetToControlled(stateFor(session))
480
+ resetToControlled(stateFor(session), session)
385
481
  return
386
482
  }
387
483
  if (event.type !== 'step/end' && event.type !== 'turn/end') return
@@ -464,14 +560,18 @@ export function apply(ctx, config) {
464
560
  messages: decision.messages.filter(message => isAllowedMessage(message, messageSources)),
465
561
  }
466
562
  }
563
+ let result = decision
467
564
  if (state.deferredSteps < policy.deferredGraceSteps) {
468
565
  state.deferredSteps += 1
469
- return {
470
- ...decision,
471
- messages: decision.messages.filter(message => !isDeferredMessage(message, deferredSources)),
566
+ result = {
567
+ ...result,
568
+ messages: result.messages.filter(message => !isDeferredMessage(message, deferredSources)),
472
569
  }
473
570
  }
474
- return decision
571
+ if (policy.instructionHint) {
572
+ result = { ...result, messages: instructionHintMessages(result.messages, state) }
573
+ }
574
+ return result
475
575
  }, { prepend: true })
476
576
 
477
577
  // Phase 1 caps the next request output budget to bootstrapMaxTokens, the
@@ -493,4 +593,4 @@ export function apply(ctx, config) {
493
593
  }
494
594
  return { ...resolved, maxTokens: policy.bootstrapMaxTokens }
495
595
  }, { prepend: true })
496
- }
596
+ }
@@ -15,20 +15,15 @@ Receives a `CUT_PASS` Cut Decision from `devflow-cut`, either through the direct
15
15
  - Depth C input: `CUT_PASS` plus the approved design contract; no Plan Pack is required.
16
16
 
17
17
  When no plan file exists, the approved design and Cut Decision form the Build Contract basis; skip the plan checker.
18
- ## Plan Review
18
+ ## Direct Execution
19
19
 
20
- Load `skills/devflow-build/references/build-methods.md` after this review and before implementation slices. It owns the detailed minimal-change and slice discipline.
20
+ Load `skills/devflow-build/references/build-methods.md` after this section and before implementation slices. It owns the detailed minimal-change and slice discipline.
21
21
 
22
- Before editing, reconcile the plan against the current codebaseexecutability review, not redesign:
22
+ There is no pre-edit plan review. The executor reads only the current task's execution spec `Files`, `Change mechanics`, `Steps`, `Verify` — from the approved plan, edits those files directly, runs `Verify`, and appends actual evidence. An actual edit or verification failure must stop and return `BUILD_BLOCKED` with the facts to `devflow-core`: the observed mismatch, affected anchor, and smallest replan decision. Do not pre-check anchors, do not guess, do not silently repair the plan.
23
23
 
24
- 1. Anchors: every `Modify` symbol/anchor and interface in the plan still exists and matches.
25
- 2. Behavior: each task's `Current behavior` still describes the code.
26
- 3. Steps: unambiguous, with verification commands that can run in this environment.
27
- 4. Skills: every skill declared in `External Skills` (Cut Decision or plan header) is actually loaded through the platform's skill mechanism, or the reason it does not apply is recorded; loading alone is not completion — Build requires the specialist's returned result, not-applicable, or failure facts. A specialist result implying structure outside the approved scope returns scope-drift facts to `devflow-core`, not silent adoption.
24
+ Every skill declared in `External Skills` (Cut Decision or plan header) must actually be loaded through the platform's skill mechanism, or the reason it does not apply recorded; loading alone is not completion — Build requires the specialist's returned result, not-applicable, or failure facts. A specialist result implying structure outside the approved scope returns scope-drift facts to `devflow-core`, not silent adoption. Skill loading is not a pre-edit view and remains mandatory.
28
25
 
29
- Any failed check, unclear instruction, or critical gap: stop and return `BUILD_BLOCKED` with the facts to `devflow-core`. Do not guess, do not silently repair the plan. Reviewing fidelity is not re-deciding the mechanism.
30
-
31
- For Depth C (no Plan Pack), run the same review against the approved design contract: confirm the symbols and behaviors it names still exist. Depth C keeps Build freedom inside the Cut Decision; it does not skip this review or the Stop Protocol.
26
+ For Depth C (no Plan Pack), the approved design contract is the execution spec: edit directly from it without a separate reconciliation pass. Depth C keeps Build freedom inside the Cut Decision; it does not skip the Stop Protocol.
32
27
 
33
28
  ## Build Contract
34
29
 
@@ -51,7 +46,7 @@ When saving a plan file, use `docs/plans/YYYY-MM-DD-<short-kebab-name>.md`, reso
51
46
 
52
47
  For multi-step work, tasks must cite the approved source, be small and verifiable, and follow the required task contract (Task: / Task type: / Files: / Interfaces: / Current behavior: / Target behavior: / Change mechanics: / Call impact: / Steps: / Acceptance: / Verify: / Comments: / Not doing:) defined in `skills/devflow-plan/SKILL.md`.
53
48
 
54
- No unresolved markers. For `Code change`, follow the recorded file symbol/anchor, `Current behavior`, `Target behavior`, `Change mechanics`, and `Call impact`; do not re-decide the implementation mechanism in Build. The verification step must retain its trigger/input, expected result, and command or manual scenario. `Documentation-only` applies only to tasks with no runtime code files and explicit `documentation-only` interfaces. No "add tests" without naming the behavior. No "handle edge cases" without naming the edge case. No "similar to Task N" shortcuts; repeat enough detail for each task to stand alone.
49
+ No unresolved markers. For `Code change`, the dispatched execution spec follows the recorded file symbol/anchor and `Change mechanics`; do not re-decide the implementation mechanism in Build. `Current behavior`, `Target behavior`, and `Call impact` are the plan author's records, not executor re-read requirements. The verification step must retain its trigger/input, expected result, and command or manual scenario. `Documentation-only` applies only to tasks with no runtime code files and explicit `documentation-only` interfaces. No "add tests" without naming the behavior. No "handle edge cases" without naming the edge case. No "similar to Task N" shortcuts; repeat enough detail for each task to stand alone.
55
50
 
56
51
  Before Build, run `node scripts/devflow-plan.js <plan-file>` when a plan is saved to a file. If not found at `scripts/devflow-plan.js` (project-level), try `~/.codex/scripts/devflow-plan.js` or `~/.claude/scripts/devflow-plan.js` (user-level). Do NOT look under `skills/scripts/`. See `core-methods.md` Script Path Resolution.
57
52
 
@@ -85,21 +80,21 @@ Rules:
85
80
 
86
81
  ## Execution Mode
87
82
 
88
- The plan's `Execution mode` (`sequential` | `single-subagent` | `fan-out`) is chosen at Plan approval and passed to Build; Build does not re-decide it. `sequential` runs tasks in dependency order as the Build agent itself; `single-subagent` delegates the whole plan to one executor subagent while the main agent only schedules; `fan-out` runs independent tasks as parallel subagents and dependent tasks in sequence after their inputs land.
83
+ The plan's `Execution mode` (`sequential` | `single-subagent` | `fan-out`) is chosen at Plan approval and passed to Build; Build does not re-decide it. `sequential` runs tasks in dependency order as the Build agent itself; `single-subagent` dispatches one task's execution spec at a time to one executor subagent while the main agent only schedules; `fan-out` runs independent tasks as parallel subagents and dependent tasks in sequence after their inputs land.
89
84
 
90
85
  ### Single-subagent dispatch
91
86
 
92
- - The main agent does not execute tasks. It dispatches the whole approved Plan Pack to one executor subagent, waits for the return, and then merges the returned evidence and enters Prove once.
93
- - The subagent runs all tasks in dependency order inside one context under the same Plan Review and Prewalk read discipline, appends actual evidence to the plan's Execution Trace, and returns the merged task results and evidence, or `BUILD_BLOCKED` facts.
87
+ - The main agent does not execute tasks. It dispatches one task's execution spec at a time to one executor subagent, waits for the return, and then merges the returned evidence and enters Prove once.
88
+ - The subagent edits that task's `Files` directly, runs its `Verify`, appends actual evidence, and returns the task results and evidence, or `BUILD_BLOCKED` facts. On DSH, one task per subagent round; the next task continues through `send_message`; a timeout or truncated return retries that task once.
94
89
  - The main agent may send one bounded follow-up when the return misses evidence; anything still incomplete is returned to `devflow-core` as `BUILD_BLOCKED` facts. The subagent never declares done, never enters Prove, and never re-decides the mode or the Cut scope.
95
90
 
96
91
  ### Fan-out dispatch
97
92
 
98
93
  - Two tasks may run in parallel only when their `Files` touch disjoint file/symbol sets and neither `Interfaces` consumes a symbol the other `Produces`; otherwise run the producer first.
99
- - Each subagent runs one task contract under the same Plan Review and Prewalk read discipline, and returns the task result or `BUILD_BLOCKED` facts.
94
+ - Each subagent receives only its task's execution spec, edits its task's `Files` directly, runs its `Verify`, and returns the task result or `BUILD_BLOCKED` facts.
100
95
  - The main agent merges returned results, reconciles cross-task file overlap, runs the unified `Diff Self-Check`, and enters `devflow-prove` once with merged evidence — never per-subagent.
101
96
 
102
- `single-subagent` and `fan-out` are scheduling only; they do not change Plan Review, Stop Protocol, Cut scope, or the single Prove gate.
97
+ `single-subagent` and `fan-out` are scheduling only; they do not change Cut scope, Stop Protocol, or the single Prove gate.
103
98
 
104
99
  ## Source Check
105
100
 
@@ -196,7 +191,7 @@ If any file has no goal link, remove that change.
196
191
  | "We'll verify everything at the end." | Verify slices when focused checks exist. |
197
192
  | "Docs changes do not need proof." | Docs/rules/skills need validation just like code. |
198
193
  | "The issue only mentions one caller." | Check sibling callers before choosing the fix location. |
199
- | "The plan is approved, so I just execute." | Plan Review comes first: stale anchors or unclear steps return `BUILD_BLOCKED` to Core. |
194
+ | "The plan is approved, so I just execute." | Right: the approved execution spec is edited directly; an actual edit or verification failure returns `BUILD_BLOCKED` to Core. |
200
195
  | "I'll infer the missing step." | Guessing past a gap is forbidden; unclear instructions return `BUILD_BLOCKED` facts. |
201
196
  | "The code is self-explanatory." | That does not waive a comment required by the approved contract, project convention, or a non-obvious boundary. |
202
197
  | "Comments will get stale." | Keep a required comment accurate or remove a stale one; a stale explanation is not a reason to skip a needed decision record. |
@@ -207,7 +202,7 @@ If any file has no goal link, remove that change.
207
202
 
208
203
  Stop executing immediately and return `BUILD_BLOCKED` with the blocking facts to `devflow-core` when:
209
204
 
210
- - a Plan Review check fails (dead anchor, stale behavior, missing interface, unclear step)
205
+ - an edit cannot be applied or a verification fails (dead anchor, stale behavior, missing interface, unclear step)
211
206
  - a dependency, tool, or declared external skill is missing and the task depends on it, or its returned failure facts block the approved work
212
207
  - verification fails repeatedly for the same task
213
208
  - the plan has a critical gap that prevents starting or continuing
@@ -228,7 +223,7 @@ Known unverified: ...
228
223
 
229
224
  Before leaving this skill, confirm:
230
225
 
231
- - [ ] Plan Review passed or concerns were returned to `devflow-core` as `BUILD_BLOCKED`.
226
+ - [ ] Direct Execution completed — each task's spec was edited directly and verified, or actual failures were returned to `devflow-core` as `BUILD_BLOCKED`.
232
227
  - [ ] Declared external skills were loaded, or the exception reason was recorded in `Skills loaded`.
233
228
  - [ ] Build contract exists.
234
229
  - [ ] Cut gates passed or were run.
@@ -18,11 +18,11 @@ Turn an A/B `CUT_PASS`-bounded approved design or confirmed Spec into one review
18
18
  1. Read only source material, code, tests, and conventions relevant to the approved scope. Load `skills/devflow-spec/references/spec-plan-methods.md` and `skills/devflow-plan/references/plan-methods.md` before applying Plan Pack mechanics.
19
19
  2. Map exact affected file responsibilities once in `## File Structure` before writing tasks. Reuse existing modules and name the intended file operation.
20
20
  3. Perform bounded real investigation and record it as task-level `Prewalk`: actual `Execution Trace`, Current Handoff Facts, and only the unfinished `Remaining Structured Worklist`.
21
- 4. Split independent deliverables into small, reviewable tasks. Each task should be understandable without referring to another task.
21
+ 4. Split independent deliverables into small, reviewable tasks. Each task should be understandable without referring to another task, and it carries its own complete execution spec(执行规范)— `Files`, `Change mechanics`, `Steps`, and `Verify` — so the executor edits directly from the task without re-reading the plan or the code for a pre-edit view(零 view).
22
22
  5. Write the plan using the required header and task contract below.
23
23
  6. Self-review Cut Decision fidelity, source coverage, File Structure, Prewalk evidence, file-operation classifications, interface consistency, concrete steps, acceptance proof, and scope exclusions.
24
24
  7. Run `node scripts/devflow-plan.js <plan-file>` when the project-level checker exists. Otherwise resolve the user-level checker according to `core-methods.md` Script Path Resolution.
25
- 8. **STOP — request user review.** On DSH, request review with the structured `ask_user_question` tool (single-select: approve / request changes). Revise and revalidate when requested. On approval, ask execution mode (single-select: `sequential` — the Build agent runs tasks in dependency order / `single-subagent` — the main agent only schedules: one subagent runs all tasks in dependency order / `fan-out` — independent tasks run as parallel subagents) and record it as the plan's optional `Execution mode` header. Then perform only a lightweight Cut-consistency review. An approved A/B Plan directly enters `devflow-build`; scope-drift facts return to `devflow-core`.
25
+ 8. **STOP — request user review.** On DSH, request review with the structured `ask_user_question` tool (single-select: approve / request changes). Revise and revalidate when requested. On approval, ask execution mode (single-select: `sequential` — the Build agent runs tasks in dependency order / `single-subagent` — the main agent only schedules: one subagent runs tasks one per round in dependency order / `fan-out` — independent tasks run as parallel subagents) and record it as the plan's optional `Execution mode` header. Then perform only a lightweight Cut-consistency review. An approved A/B Plan directly enters `devflow-build`; scope-drift facts return to `devflow-core`.
26
26
 
27
27
  Default landing is `docs/plans/YYYY-MM-DD-<short-kebab-name>.md`, resolved from the target project root. Do not place implementation plans in `docs/features/` or `docs/specs/`.
28
28
 
@@ -56,6 +56,8 @@ Inherit `External Skills` from the Cut Decision unchanged; the Plan Pack carries
56
56
 
57
57
  `Execution mode` is not part of Cut scope and does not change the checker. It is asked at approval and recorded so Build knows how to run tasks: sequentially as the Build agent itself, through one delegated subagent while the main agent only schedules, or fan out independent tasks to parallel subagents.
58
58
 
59
+ Each task's `Files`, `Change mechanics`, `Steps`, and `Verify` form the only execution basis(执行规范)handed to the executor: dispatch sends just these fields, and the executor edits directly from them without a pre-edit view of the plan document, the code, or the anchors. `Read-basis` / `Live anchors` remain the plan author's evidence record, not executor re-read instructions.
60
+
59
61
  ## Required Task Contract
60
62
 
61
63
  ```text
@@ -90,7 +92,7 @@ Execution Trace:
90
92
  - Verified: <actual check> → <observed result; or "none yet">.
91
93
 
92
94
  Current Handoff Facts:
93
- - Target anchors: <current file, symbol, or range that Build minimally re-reads>.
95
+ - Target anchors: <current file, symbol, or range the plan author verified (evidence record, not executor re-read instruction)>.
94
96
  - Nearby convention: <comparable inspected code and observed convention; or "no comparable code found">.
95
97
  - Direct path: <traced callers, collaborators, boundaries, affected tests; or "none">.
96
98
  - Current constraints: <observed contract, ordering, errors, compatibility; or "none">.
@@ -104,7 +106,7 @@ Remaining Structured Worklist:
104
106
  Done when: <fact proving this action is complete>.
105
107
  ```
106
108
 
107
- `File Structure` is one responsibility map, not a fixed architecture rule. For every non-trivial Code change, every task must carry a `Prewalk`. Each trace row records an action actually performed and its observed result; it cannot describe planned work. `Remaining Structured Worklist` contains only unfinished actions. Each item needs `Anchors`, `Verify`, and `Done when`; cap one task at 12 items. Build reads the latest trace first, minimally re-reads the current item's anchors and directly changed neighbor, appends actual evidence after the item, and returns facts to `devflow-core` if anchors, contracts, conventions, direct dependencies, responsibility, or directly necessary touch set contradict the handoff. Documentation-only tasks retain their existing exception.
109
+ `File Structure` is one responsibility map, not a fixed architecture rule. For every non-trivial Code change, every task must carry a `Prewalk`. Each trace row records an action actually performed and its observed result; it cannot describe planned work. `Remaining Structured Worklist` contains only unfinished actions. Each item needs `Anchors`, `Verify`, and `Done when`; cap one task at 12 items. The executor reads the current task's execution spec (`Files`, `Change mechanics`, `Steps`, `Verify`), edits directly, runs `Verify`, appends actual evidence, and returns the observed difference as facts to `devflow-core` only when an edit or verification actually fails there is no pre-edit plan or code view. Documentation-only tasks retain their existing exception.
108
110
 
109
111
  Use only `Create`, `Modify`, and `Test` file-operation labels. For a `Code change`, every existing-file row must name a symbol or stable anchor; `Create` rows use `new file`. `Current behavior`, `Target behavior`, `Change mechanics`, and `Call impact` are mandatory. `Change mechanics` must contain the smallest code snippet, pseudocode, or exact replacement rule that removes implementation inference. Interfaces name exact symbols and input/output shape. The verification step and `Verify` field name the trigger/input, expected result, and runnable command or manual scenario.
110
112
 
@@ -112,7 +114,7 @@ Use only `Create`, `Modify`, and `Test` file-operation labels. For a `Code chang
112
114
 
113
115
  ## Boundaries
114
116
 
115
- Plan generation does not repeat Cut, perform Build or Prove, prescribe independent review, test-first workflow, version-control task steps, or execute automatically. It converts `CUT_PASS` into a static construction checklist. The checker validates static structure; it does not judge architecture or lifecycle state.
117
+ Plan generation does not repeat Cut, perform Build or Prove, prescribe independent review, test-first workflow, version-control task steps, or execute automatically. It converts `CUT_PASS` into a static construction checklist. The checker validates static structure; it does not judge architecture or lifecycle state. Plan generation writes the execution spec(执行规范); the zero-view(零 view)execution discipline belongs to `plan-methods.md` and `devflow-build` — a Plan Pack must not include execution-phase re-read or pre-edit review instructions.
116
118
 
117
119
  ## Anti-Rationalization
118
120
 
@@ -136,7 +138,7 @@ Before leaving this skill, confirm:
136
138
  - [ ] `Spec coverage` maps the source to plan tasks.
137
139
  - [ ] Header, constraints, File Structure, interfaces, concrete steps, acceptance, verification, context-specific comments, exclusions, and task-level Prewalk records are present.
138
140
  - [ ] Each trace entry is an observed past action/result; each remaining worklist item is bounded, verified, and fact-complete.
139
- - [ ] Every task is independently understandable, requires only minimal anchor reread, and has no unresolved or vague placeholder.
141
+ - [ ] Every task is independently understandable, requires no pre-edit read, and has no unresolved or vague placeholder.
140
142
  - [ ] The checker passed when available.
141
143
  - [ ] The user reviewed the written plan.
142
144
  - [ ] An approved A/B Plan entered `devflow-build`; any scope-drift facts returned to `devflow-core`.
@@ -29,14 +29,14 @@ Execution Trace:
29
29
  - Verified: [actual check] → [observed result; or "none yet"].
30
30
 
31
31
  Current Handoff Facts:
32
- - Target anchors: [minimum current anchors for the next executor].
32
+ - Target anchors: [current file/symbol/range the plan author verified; evidence record, not executor re-read instruction].
33
33
  - Nearby convention: [inspected comparable code and observed convention; or "no comparable code found"].
34
34
  - Direct path: [traced callers, collaborators, boundaries, affected tests; or "none"].
35
35
  - Current constraints: [observed contract, ordering, error behavior, compatibility; or "none"].
36
36
  - Planned touch set: [remaining expected files/symbols and reason].
37
37
  - Risks / stop conditions: [facts that require Core replan; or "none beyond ordinary Plan drift"].
38
- - Read-basis: [已读文件清单——执行者无需重读].
39
- - Live anchors: [仅需现场确认的锚点——执行者只读这些].
38
+ - Read-basis: [已读文件清单——计划作者的证据簿记,执行者不重读].
39
+ - Live anchors: [计划作者已确认的锚点——执行者不重读,仅作失败回报时的定位].
40
40
 
41
41
  Remaining Structured Worklist:
42
42
  - [ ] [one independently completable remaining action with file/symbol and expected outcome].
@@ -61,14 +61,14 @@ Remaining Structured Worklist:
61
61
 
62
62
  ## Delegated Execution
63
63
 
64
- A delegated executor reads the latest trace, then minimally re-reads the current work item's anchors and directly changed neighbor. It does not repeat File Structure decisions or broadly reread the repository by default. The executor determines its read set from `Current Handoff Facts`: it must not re-read the `Read-basis` list and only live-verifies the `Live anchors`; anchor contradiction still returns facts to `devflow-core`.
64
+ A delegated executor the main agent itself, one delegated subagent, or one fan-out subagent — never re-reads the plan document, the latest trace, the anchors, the goal, or the code for a pre-edit view. It receives only the current task's execution spec (`Files`, exact replacement rules, `Steps`, `Verify`), edits those files directly, runs the task's `Verify` command, and returns actual evidence or failure facts to the orchestrating Build agent. `Read-basis` and `Live anchors` stay in the plan as the plan author's evidence record (the checker requires them); they are not executor re-read instructions.
65
65
 
66
- Stop and return facts to `devflow-core` when the minimal reread shows a contradiction in any target anchor, direct caller, contract, local convention, dependency, side effect, affected test, responsibility, or directly necessary touch set. The return identifies the observed mismatch, affected anchor, invalidated handoff fact, blocked verification, and smallest replan decision. An obvious stale line reference may be corrected without returning only when the symbol, contract, responsibility, and intended outcome are unchanged.
66
+ When an edit cannot be applied or a `Verify` fails, the executor returns the observed difference affected file/anchor, actual behavior, blocked verification, and smallest replan decision as facts to `devflow-core`; it does not pre-check anchors and does not guess past a failed edit. A stale line reference may be corrected without returning only when the symbol, contract, responsibility, and intended outcome are unchanged.
67
67
 
68
68
  ### Fan-out
69
69
 
70
- When the plan's `Execution mode` is `fan-out`, one Build orchestrator partitions tasks into parallel groups and dispatches each task to a subagent. Every subagent follows the same per-task read discipline above: read the latest trace, minimally re-read only its task's anchors (`Read-basis` / `Live anchors`), execute only its task's `Files`, and return evidence or contradiction facts. Two tasks may run in parallel only when their `Files` touch disjoint file/symbol sets and neither `Interfaces` consumes a symbol the other `Produces`; tasks sharing a file/symbol or with a consume/produce dependency run in sequence. The orchestrator merges returned results, reconciles cross-task overlap, and enters Prove once with merged evidence.
70
+ When the plan's `Execution mode` is `fan-out`, one Build orchestrator partitions tasks into parallel groups and dispatches each task to a subagent. Every subagent receives only its own task's execution spec, edits its task's `Files` directly, runs its task's `Verify`, and returns evidence or failure facts; it does not re-read the plan, the trace, the anchors, or the code. Two tasks may run in parallel only when their `Files` touch disjoint file/symbol sets and neither `Interfaces` consumes a symbol the other `Produces`; tasks sharing a file/symbol or with a consume/produce dependency run in sequence. The orchestrator merges returned results, reconciles cross-task overlap, and enters Prove once with merged evidence.
71
71
 
72
72
  ### Single-subagent
73
73
 
74
- When the plan's `Execution mode` is `single-subagent`, the main agent only schedules: it dispatches the whole approved Plan Pack to one executor subagent, waits for the return, then merges the returned evidence and enters Prove once. The subagent runs all tasks in dependency order inside one context under the same per-task read discipline above: read the latest trace, minimally re-read only the current item's `Anchors` / `Live anchors`, execute only the task's `Files`, append actual evidence to the plan trace, and return merged results and evidence, or `BUILD_BLOCKED` facts. Nothing runs in parallel; prefer this mode for small to medium plans or plans whose tasks are strongly dependent, and keep `fan-out` for large parallel plans.
74
+ When the plan's `Execution mode` is `single-subagent`, the main agent only schedules: it dispatches one task's execution spec at a time to one executor subagent, waits for the return, then merges the returned evidence and enters Prove once. The main agent dispatches one task at a time only that task's execution spec, not the whole plan. The subagent edits that task's `Files` directly, runs its `Verify`, appends actual evidence, and returns the task results and evidence or `BUILD_BLOCKED` facts; the next task continues the same subagent conversation through `send_message`. On DeepSeek Harness (DSH), subagent turns are time-bounded, so one task per round is the norm; a timeout or truncated return retries that one task once with a narrower instruction. The subagent never re-reads the plan, the trace, the anchors, or the code for a pre-edit view. Nothing runs in parallel; prefer this mode for small to medium plans or plans whose tasks are strongly dependent, and keep `fan-out` for large parallel plans.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-core/dsh-devflow",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "DevFlow for DeepSeek Harness: devflow-2 agent preset + skills + commands + verification scripts, synced into ~/.dsh on host startup.",
5
5
  "type": "module",
6
6
  "engines": {
@@ -30,4 +30,4 @@
30
30
  "sync-assets": "node scripts/sync-assets.js",
31
31
  "test": "node test/sync.test.js"
32
32
  }
33
- }
33
+ }