easy-coding-harness 0.5.3 → 0.6.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.
- package/CHANGELOG.md +11 -0
- package/README.md +8 -10
- package/dist/cli.js +134 -2
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/templates/common/bundled-skills/ec-init/SKILL.md +1 -1
- package/templates/common/bundled-skills/ec-meta/references/local-architecture/README.md +8 -5
- package/templates/common/skills/ec-analysis/SKILL.md +9 -8
- package/templates/common/skills/ec-brainstorming/SKILL.md +2 -1
- package/templates/common/skills/ec-implementing/SKILL.md +5 -4
- package/templates/common/skills/ec-memory/SKILL.md +42 -20
- package/templates/common/skills/ec-reviewing/SKILL.md +6 -3
- package/templates/common/skills/ec-task-close/SKILL.md +1 -1
- package/templates/common/skills/ec-verification/SKILL.md +16 -21
- package/templates/common/skills/ec-workflow/SKILL.md +70 -62
- package/templates/main-constraint/AGENTS.md.tpl +10 -6
- package/templates/main-constraint/CLAUDE.md.tpl +10 -6
- package/templates/runtime/memory/SHORT_MEMORY_TEMPLATE.md +2 -0
- package/templates/shared-hooks/easy_coding_state.py +560 -33
- package/templates/shared-hooks/inject-workflow-state.py +1 -176
- package/templates/shared-hooks/session-start.py +2 -1
package/package.json
CHANGED
|
@@ -162,7 +162,7 @@ agent must be able to see what was generated and on what evidence.
|
|
|
162
162
|
- TEST_STRATEGY.md (skeleton for the chosen framework)
|
|
163
163
|
3. **Skip ABSTRACT.md** — no architecture exists yet. Note in init_log:
|
|
164
164
|
"ABSTRACT pending; ec-memory backfills after the first substantive task." (ec-memory
|
|
165
|
-
detects the missing file during
|
|
165
|
+
detects the missing file during MEMORY and generates it from the then-current code.)
|
|
166
166
|
4. Memory migration probe and memory init, same as iterative steps 5-7.
|
|
167
167
|
5. Recommend: design first with `{{skill_trigger}}ec-brainstorming`, then build via
|
|
168
168
|
`{{skill_trigger}}ec-workflow`.
|
|
@@ -42,10 +42,12 @@ analysis, workflow operation). The CLI never analyzes the project.
|
|
|
42
42
|
|
|
43
43
|
## Workflow state machine
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
`INIT → ANALYSIS →
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
6 work stages + 2 terminals, owned by ec-workflow:
|
|
46
|
+
`INIT → ANALYSIS → IMPLEMENT → REVIEW → VERIFICATION → MEMORY → COMPLETE`, plus `CLOSED`
|
|
47
|
+
(user abort, no memory flow). Every legal stage edge records `task.json.pending_transition`
|
|
48
|
+
and requires explicit user confirmation by default. VERIFICATION remains the fresh-evidence
|
|
49
|
+
hard gate, and MEMORY keeps the conditional long-memory threshold gate. The active task
|
|
50
|
+
pointer lives in `sessions/{ppid}.json`;
|
|
49
51
|
when the task reaches `COMPLETE` or `CLOSED`, the state API clears `current_task` so the
|
|
50
52
|
session returns to Ready. Each task's stage persists in its `task.json`. Hooks inject the
|
|
51
53
|
session and task state as breadcrumbs so every reply can render the status line.
|
|
@@ -57,7 +59,8 @@ stage in `task.json`; no data is lost. Each task folder is self-contained.
|
|
|
57
59
|
|
|
58
60
|
## Task persistence
|
|
59
61
|
|
|
60
|
-
Each task is a folder. `task.json` is metadata
|
|
62
|
+
Each task is a folder. `task.json` is metadata, including the current stage and any
|
|
63
|
+
`pending_transition`; `dev-spec.md` is the human-readable plan;
|
|
61
64
|
`execution.jsonl` is an append-only plan-and-log (one `plan` record, then `dispatch`/`result`
|
|
62
65
|
/`review`/`verify`/`handoff` records). Because plan and log live on disk, not in an agent's
|
|
63
66
|
context window, a task survives session end and agent switches with zero information loss.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ec-analysis
|
|
3
|
-
description: ANALYSIS-stage skill. Use when ec-workflow enters ANALYSIS. Creates the dev-spec skeleton FIRST (template-first), then fills incrementally — producing the narrative plan, execution plan (execution.jsonl), and test strategy. Ends
|
|
3
|
+
description: ANALYSIS-stage skill. Use when ec-workflow enters ANALYSIS. Creates the dev-spec skeleton FIRST (template-first), then fills incrementally — producing the narrative plan, execution plan (execution.jsonl), and test strategy. Ends by requesting the confirmed edge to IMPLEMENT. Grounds every conclusion in real code, never restates the requirement.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
> **SKELETON FIRST — your first two tool calls MUST be: (1) Read `.easy-coding/templates/dev-spec-skeleton.md`, (2) Write its EXACT content to the task's dev-spec.md. No exceptions. Do not analyze or think before the skeleton file exists on disk.**
|
|
@@ -42,8 +42,8 @@ Communicate with the user in the user's language.
|
|
|
42
42
|
which subset this round?" as an explicit item in 待用户决策 for the user to decide. Never
|
|
43
43
|
make a scope-narrowing decision yourself and present it as settled. Never fabricate a
|
|
44
44
|
premise such as "the user already fixed scope X in INIT" or "auto_mode already selected Y"
|
|
45
|
-
to justify narrowing — `auto_mode` only waives
|
|
46
|
-
carries NO scope or delivery-form decision whatsoever.
|
|
45
|
+
to justify narrowing — `auto_mode` only waives stage-boundary prompts under an explicit
|
|
46
|
+
autonomous user request and carries NO scope or delivery-form decision whatsoever.
|
|
47
47
|
6. **改动范围 lists ONLY real project code.** The 改动范围 table carries only changes to real
|
|
48
48
|
project source/config files. Any harness artifact under `.easy-coding/` (dev-spec.md,
|
|
49
49
|
execution.jsonl, test-strategy.md, memory files, generated reports, etc.) is FORBIDDEN in
|
|
@@ -218,7 +218,8 @@ VERIFICATION baseline).
|
|
|
218
218
|
|
|
219
219
|
> 修订同样受 HARD RULE 5/6 约束:用户的修订诉求若是扩大或细化代码改动,不得借机把任务降级为"出报告";范围收窄仍须作为 待用户决策 项由用户确认。
|
|
220
220
|
|
|
221
|
-
On user revision
|
|
221
|
+
On user revision or Other feedback while ANALYSIS has a pending transition, first cancel the
|
|
222
|
+
pending edge. Do NOT reply with only a change summary.
|
|
222
223
|
Re-output the COMPLETE revised dev-spec.md:
|
|
223
224
|
|
|
224
225
|
1. Prepend a `### 修订摘要` listing each user request and its impact on the plan. If the
|
|
@@ -227,11 +228,11 @@ Re-output the COMPLETE revised dev-spec.md:
|
|
|
227
228
|
sections), incorporating all revisions.
|
|
228
229
|
3. Overwrite the `plan` record in execution.jsonl with the new strategy.
|
|
229
230
|
4. Update test-strategy.md if test scope changed.
|
|
230
|
-
5.
|
|
231
|
+
5. Request ANALYSIS -> IMPLEMENT again and present the standard confirmation/handoff/Other gate.
|
|
231
232
|
|
|
232
233
|
## End state
|
|
233
234
|
|
|
234
235
|
Read dev-spec.md back from disk and output the COMPLETE content as your reply to the user —
|
|
235
|
-
not a summary, not a different format, not a table you invented. Then
|
|
236
|
-
|
|
237
|
-
skill.
|
|
236
|
+
not a summary, not a different format, not a table you invented. Then ask ec-workflow to
|
|
237
|
+
record `pending_transition: ANALYSIS -> IMPLEMENT`, present the standard boundary choices,
|
|
238
|
+
and stop. Never start implementing from this skill.
|
|
@@ -66,7 +66,8 @@ After saving the design doc, ask the user: "Design confirmed. Start a task based
|
|
|
66
66
|
design now?" Offer two options:
|
|
67
67
|
|
|
68
68
|
1. **Start task now** — invoke `{{skill_trigger}}ec-workflow` with the design topic as the
|
|
69
|
-
task prompt. ec-workflow will create the task
|
|
69
|
+
task prompt. ec-workflow will create the task and enter INIT. After INIT completes, it
|
|
70
|
+
presents the standard confirmation/handoff/Other gate before entering ANALYSIS.
|
|
70
71
|
ec-analysis will discover the design doc in `.easy-coding/spec/` and use it as input.
|
|
71
72
|
2. **Later** — tell the user the design is saved and they can run
|
|
72
73
|
`{{skill_trigger}}ec-workflow` whenever ready.
|
|
@@ -46,8 +46,8 @@ EVERY STRATEGY = MANDATORY SUB-AGENT DISPATCH. NO EXCEPTIONS.
|
|
|
46
46
|
|
|
47
47
|
You MUST dispatch sub-agents using {{sub_agent_dispatch}} for every unit, whatever the
|
|
48
48
|
strategy. You are FORBIDDEN from implementing any unit yourself in the main agent. Doing the
|
|
49
|
-
work inline instead of dispatching is a protocol violation equivalent to
|
|
50
|
-
|
|
49
|
+
work inline instead of dispatching is a protocol violation equivalent to bypassing the
|
|
50
|
+
ANALYSIS -> IMPLEMENT confirmation gate.
|
|
51
51
|
|
|
52
52
|
Self-check before writing ANY implementation code:
|
|
53
53
|
- Am I about to write implementation code in the main agent? → STOP. Dispatch a sub-agent.
|
|
@@ -107,8 +107,9 @@ let sub-agents re-dispatch each other.
|
|
|
107
107
|
|
|
108
108
|
## End state
|
|
109
109
|
|
|
110
|
-
All units done and self-audited → hand back to ec-workflow to
|
|
111
|
-
|
|
110
|
+
All units done and self-audited → hand back to ec-workflow to request IMPLEMENT -> REVIEW and
|
|
111
|
+
wait at the standard confirmation/handoff/Other gate. If something invalidates the plan,
|
|
112
|
+
request IMPLEMENT -> ANALYSIS and wait at the same gate instead of improvising.
|
|
112
113
|
|
|
113
114
|
## Self-check gates (before handing back)
|
|
114
115
|
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ec-memory
|
|
3
|
-
description:
|
|
3
|
+
description: MEMORY-stage skill — part of the archive flow, triggered only after user acceptance and a confirmed stage edge. Writes one schema-v2 short memory, then runs the authoritative conditional long-memory gate, performs optional distillation, and requests COMPLETE.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# ec-memory — archive what was learned
|
|
7
7
|
|
|
8
|
-
ec-workflow dispatches you during
|
|
9
|
-
|
|
8
|
+
ec-workflow dispatches you during MEMORY, which runs only after the user accepts the task and
|
|
9
|
+
confirms entry. Inputs: the task's `dev-spec.md`, `execution.jsonl` (the `result` and
|
|
10
10
|
`verify` records are precise source material), the changed-files list, existing memory files.
|
|
11
11
|
|
|
12
12
|
Communicate with the user in the user's language. Memory file content follows the project's
|
|
13
13
|
recorded comment/doc language.
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## Step 1 — write one short memory entry
|
|
16
16
|
|
|
17
17
|
Create one file under `.easy-coding/memory/short/` following the format in
|
|
18
18
|
`.easy-coding/memory/SHORT_MEMORY_TEMPLATE.md`. File naming convention:
|
|
@@ -23,6 +23,7 @@ Frontmatter (all fields required):
|
|
|
23
23
|
---
|
|
24
24
|
memory_schema: 2
|
|
25
25
|
id: SM-{YYYYMMDD}-{NN}
|
|
26
|
+
source_task: {current task id, exact}
|
|
26
27
|
date: {YYYY-MM-DD}
|
|
27
28
|
task_type: {feature | bugfix | refactor | perf | doc | workflow}
|
|
28
29
|
project_mode: {startup | iteration}
|
|
@@ -45,6 +46,13 @@ conversation. Refer to SHORT_MEMORY_TEMPLATE.md for the complete section format.
|
|
|
45
46
|
|
|
46
47
|
If the task was cross-repo, record the repo names involved and the collaboration reason.
|
|
47
48
|
|
|
49
|
+
After the file is successfully written, record the checkpoint immediately:
|
|
50
|
+
`{{PYTHON_CMD}} {{platform_config_dir}}/hooks/easy_coding_state.py memory-short-complete --session-file <P> --file "<relative-short-memory-path>" --agent <agent-id>`.
|
|
51
|
+
Use the returned `status_context` as authoritative. On resume, if `memory_progress` already
|
|
52
|
+
shows `short_memory_written:true`, do not create a duplicate entry; continue from Step 2.
|
|
53
|
+
The state API validates `memory_schema: 2`, requires `source_task` to equal the current task id,
|
|
54
|
+
and fingerprints the file. Do not reuse an older task's memory file as this checkpoint.
|
|
55
|
+
|
|
48
56
|
## Supermodule memory routing
|
|
49
57
|
|
|
50
58
|
If the current project config contains `supermodule.role: super-parent`, archive memory by
|
|
@@ -67,26 +75,27 @@ create a new one instead. Short memories serve as both a recent-detail sliding w
|
|
|
67
75
|
distillation buffer for long-term memory.
|
|
68
76
|
|
|
69
77
|
**Sliding window (informational):** The short memory directory has a soft cap defined by
|
|
70
|
-
`memory.short_term_max` (default 10).
|
|
71
|
-
|
|
72
|
-
responsibility and only runs when the threshold is exceeded.
|
|
78
|
+
`memory.short_term_max` (default 10). Step 1 only writes and checkpoints one entry per
|
|
79
|
+
completed task. It never decides whether to distill.
|
|
73
80
|
|
|
74
|
-
##
|
|
81
|
+
## Step 2 — run the long-memory gate (CONDITIONAL)
|
|
75
82
|
|
|
76
83
|
<HARD-GATE>
|
|
77
|
-
|
|
84
|
+
LONG-MEMORY WORK IS CONTROLLED BY THE STATE API `memory` INSTRUCTION.
|
|
78
85
|
|
|
79
86
|
Before performing ANY distillation work:
|
|
80
|
-
1.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
87
|
+
1. After Step 1 is checkpointed, call
|
|
88
|
+
`{{PYTHON_CMD}} {{platform_config_dir}}/hooks/easy_coding_state.py memory-instruction --session-file <P>`.
|
|
89
|
+
This ordering is mandatory: the current task's short entry must be counted first.
|
|
90
|
+
The first successful call is frozen in `memory_progress.instruction`; resumed work reuses
|
|
91
|
+
the same action and trim count even after consumed short files are deleted.
|
|
92
|
+
2. Treat the returned `memory.action` as authoritative. Do NOT recount short memories yourself and
|
|
84
93
|
do NOT override the state API instruction with prompt reasoning.
|
|
85
|
-
3. If `action == "no-op"`: output "
|
|
86
|
-
threshold = {short_term_max})"
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
94
|
+
3. If `action == "no-op"`: output "MEMORY: long-memory no-op (short memory count =
|
|
95
|
+
{short_count}, threshold = {short_term_max})". Do NOT read or modify long memory files.
|
|
96
|
+
4. If `action == "distill"`: treat `memory.candidate_files` and `memory.kept_files` as the
|
|
97
|
+
frozen authoritative sets. Distill and delete exactly `candidate_files`; preserve every
|
|
98
|
+
`kept_files` entry. Do not rebuild either set from the live directory.
|
|
90
99
|
|
|
91
100
|
This gate is absolute. Even a single short memory entry below threshold does NOT trigger
|
|
92
101
|
long-term compression regardless of any other signal.
|
|
@@ -100,8 +109,8 @@ Three-file long memory:
|
|
|
100
109
|
- `TECHNICAL.md` — architecture decisions, implementation patterns, gotchas.
|
|
101
110
|
|
|
102
111
|
Distillation steps:
|
|
103
|
-
1. Use `
|
|
104
|
-
`
|
|
112
|
+
1. Use `memory.candidate_files` and `memory.kept_files`; their sizes correspond to
|
|
113
|
+
`memory.trim_count` and the retained window calculated at instruction time.
|
|
105
114
|
2. Read the `target_long` of candidate short memories; route to business/technical.
|
|
106
115
|
3. **Progressive loading** — read only the existing long entries matching this round's
|
|
107
116
|
domain/tags/related_files. No unbounded whole-repo memory scan.
|
|
@@ -116,6 +125,19 @@ Distillation steps:
|
|
|
116
125
|
This is sliding-window consumption after successful distillation, not destructive
|
|
117
126
|
deletion of durable long-term knowledge.
|
|
118
127
|
|
|
128
|
+
After either branch succeeds, record completion with the same authoritative action:
|
|
129
|
+
`{{PYTHON_CMD}} {{platform_config_dir}}/hooks/easy_coding_state.py memory-complete --session-file <P> --action <no-op|distill> --agent <agent-id>`.
|
|
130
|
+
The state API rejects an action that disagrees with the current threshold calculation.
|
|
131
|
+
For `distill`, it also rejects completion while any frozen candidate still exists or any
|
|
132
|
+
frozen retained file is missing. A candidate checkpoint may disappear only because it is
|
|
133
|
+
explicitly listed in `candidate_files`.
|
|
134
|
+
|
|
135
|
+
## Step 3 — request COMPLETE
|
|
136
|
+
|
|
137
|
+
Only after `memory_progress.completed:true`, hand control to ec-workflow to request
|
|
138
|
+
MEMORY -> COMPLETE. Present the standard confirmation/handoff/Other gate and stop. Do not
|
|
139
|
+
mark the task COMPLETE automatically.
|
|
140
|
+
|
|
119
141
|
## ABSTRACT backfill / update
|
|
120
142
|
|
|
121
143
|
While distilling technical memory, if you detect an architecture change — module added or
|
|
@@ -30,9 +30,9 @@ result. No finding without a location.
|
|
|
30
30
|
|
|
31
31
|
## Verdict (exactly one)
|
|
32
32
|
|
|
33
|
-
- `accept` — all dimensions pass.
|
|
33
|
+
- `accept` — all dimensions pass. Request REVIEW -> VERIFICATION.
|
|
34
34
|
- `fix` — problems found, fixable within the current plan. Auto-fix via sub-agents (see below).
|
|
35
|
-
- `replan` — the plan itself is flawed (wrong approach, missing design).
|
|
35
|
+
- `replan` — the plan itself is flawed (wrong approach, missing design). Request REVIEW -> ANALYSIS.
|
|
36
36
|
- `blocked` — external blocker (missing dependency, environment). Pause and report.
|
|
37
37
|
|
|
38
38
|
## Auto-fix flow (on `fix` verdict)
|
|
@@ -46,7 +46,7 @@ defects, not design decisions.
|
|
|
46
46
|
ONLY escalate to the user when:
|
|
47
47
|
- The fix requires a DESIGN CHOICE (two equally valid approaches, ambiguous requirement)
|
|
48
48
|
- The fix would change the public API contract beyond what the dev-spec specifies
|
|
49
|
-
- The finding contradicts something the user explicitly
|
|
49
|
+
- The finding contradicts something the user explicitly confirmed at a stage boundary
|
|
50
50
|
</HARD-GATE>
|
|
51
51
|
|
|
52
52
|
Fix dispatch flow:
|
|
@@ -88,3 +88,6 @@ Platform spawn rule: {{platform_spawn_instruction}}
|
|
|
88
88
|
Append `review` records to execution.jsonl, one per dimension:
|
|
89
89
|
`{"type":"review","dimension":"correctness","findings":[{"file":"...","line":42,"issue":"...","severity":"warn"}]}`.
|
|
90
90
|
Then state the verdict and hand back to ec-workflow.
|
|
91
|
+
For `accept` or `replan`, ec-workflow records the corresponding pending transition and presents
|
|
92
|
+
the standard confirmation/handoff/Other gate. A `fix` round stays inside REVIEW and therefore
|
|
93
|
+
does not create a status transition unless the outcome changes.
|
|
@@ -24,7 +24,7 @@ when you recognize abandonment intent in the user's message.
|
|
|
24
24
|
clears session `current_task` so the next hook injection returns to Ready.
|
|
25
25
|
Use the returned `status_context` as the authoritative status source for the rest of the
|
|
26
26
|
current turn.
|
|
27
|
-
4. **No memory flow.** Do not run
|
|
27
|
+
4. **No memory flow.** Do not run MEMORY. An incomplete task's memory is dirty data.
|
|
28
28
|
5. **Linked tasks.** If the task has `spawned_from` or `spawned_tasks`, note the closure fact
|
|
29
29
|
on the relation so a future agent understands the chain.
|
|
30
30
|
6. Optionally append a closure note to `execution.jsonl` if there is context worth keeping for
|
|
@@ -54,7 +54,8 @@ Append one `verify` record per check:
|
|
|
54
54
|
|
|
55
55
|
- All three pass AND coverage satisfied → present the verification result; wait for user
|
|
56
56
|
acceptance. Do NOT archive yet.
|
|
57
|
-
- Any failure → append the failing `verify` record, summarize failures,
|
|
57
|
+
- Any failure → append the failing `verify` record, summarize failures, request
|
|
58
|
+
VERIFICATION -> IMPLEMENT, and wait at the standard confirmation/handoff/Other gate.
|
|
58
59
|
|
|
59
60
|
## 4. User acceptance and repair loop
|
|
60
61
|
|
|
@@ -62,9 +63,10 @@ After a green gate, present an acceptance summary: what changed (files + summari
|
|
|
62
63
|
verification results (lint/type/test), and the coverage status. Then the user takes time to
|
|
63
64
|
test manually. Their response routes:
|
|
64
65
|
|
|
65
|
-
- **"accepted"** →
|
|
66
|
+
- **"accepted"** → request VERIFICATION -> MEMORY and present the standard boundary gate.
|
|
66
67
|
- **"problem here"** → scope judgment against the dev-spec:
|
|
67
|
-
- in scope →
|
|
68
|
+
- in scope → request VERIFICATION -> IMPLEMENT, then re-REVIEW → re-VERIFICATION after
|
|
69
|
+
the user confirms each stage edge.
|
|
68
70
|
- out of scope → propose a new task (`spawned_from` = current task id); the current task
|
|
69
71
|
may archive now (if already satisfactory) or stay suspended.
|
|
70
72
|
- **"cancel"** → ec-task-close.
|
|
@@ -72,21 +74,14 @@ test manually. Their response routes:
|
|
|
72
74
|
Repair sizing: a trivial tweak is fixed and re-verified inside VERIFICATION; a logic/structure
|
|
73
75
|
change formally returns to IMPLEMENT and re-walks REVIEW → VERIFICATION.
|
|
74
76
|
|
|
75
|
-
## 5. Archive
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
3. COMPLETE — after MEMORY_LONG returns, call
|
|
87
|
-
`{{PYTHON_CMD}} {{platform_config_dir}}/hooks/easy_coding_state.py transition --session-file <P> --stage COMPLETE --agent <agent-id>`,
|
|
88
|
-
which clears session `current_task` for the completed task. Use the returned
|
|
89
|
-
`status_context`, then output the task summary (what was done, files changed, key
|
|
90
|
-
decisions).
|
|
91
|
-
|
|
92
|
-
Hand control back to ec-workflow at each transition; ec-workflow owns the stage writes.
|
|
77
|
+
## 5. Archive entry (only after acceptance)
|
|
78
|
+
|
|
79
|
+
Acceptance does not mutate the stage directly. Hand control to ec-workflow to call
|
|
80
|
+
`request-transition --stage MEMORY`, then present:
|
|
81
|
+
1. Confirm entering MEMORY
|
|
82
|
+
2. Hand off to another agent
|
|
83
|
+
3. Other (native free-form Other, or the third text option)
|
|
84
|
+
|
|
85
|
+
Only after confirmation may ec-workflow consume the pending edge and dispatch ec-memory.
|
|
86
|
+
ec-memory owns both short-memory creation and the conditional long-memory gate inside the
|
|
87
|
+
single MEMORY stage. It later requests MEMORY -> COMPLETE and waits for a separate confirmation.
|
|
@@ -65,27 +65,24 @@ replies are English.
|
|
|
65
65
|
## State machine
|
|
66
66
|
|
|
67
67
|
```
|
|
68
|
-
INIT -> ANALYSIS ->
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
MEMORY_SHORT -> MEMORY_LONG -> COMPLETE
|
|
68
|
+
INIT -> ANALYSIS -> IMPLEMENT -> REVIEW -> VERIFICATION -> MEMORY -> COMPLETE
|
|
69
|
+
^ ^ | |
|
|
70
|
+
+-- replan ---+ +--- fix -----+
|
|
71
|
+
^ |
|
|
72
|
+
+------- repair ----------+
|
|
73
|
+
every edge --[explicit user confirmation by default]--> target stage
|
|
75
74
|
any stage --[user abort via ec-task-close]--> CLOSED
|
|
76
75
|
```
|
|
77
76
|
|
|
78
77
|
| Stage | Owner skill | What happens | Exit condition |
|
|
79
78
|
|---|---|---|---|
|
|
80
|
-
| INIT | ec-workflow | collect context, settle scope AND delivery form (change code vs. produce a document) |
|
|
81
|
-
| ANALYSIS | ec-analysis | dev-spec + execution plan + test strategy | analysis presented |
|
|
82
|
-
|
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
|
|
|
86
|
-
|
|
|
87
|
-
| MEMORY_LONG | ec-memory | archive: long memory distillation (conditional — no-op when short memory is under threshold) | state API `memory_long` instruction handled |
|
|
88
|
-
| COMPLETE | ec-workflow | clear current_task, set task status, summary | terminal |
|
|
79
|
+
| INIT | ec-workflow | collect context, settle scope AND delivery form (change code vs. produce a document) | work complete; request ANALYSIS |
|
|
80
|
+
| ANALYSIS | ec-analysis | dev-spec + execution plan + test strategy | analysis presented; request IMPLEMENT |
|
|
81
|
+
| IMPLEMENT | ec-implementing | code changes per confirmed plan | all units done; request REVIEW |
|
|
82
|
+
| REVIEW | ec-reviewing | multi-dimension code review | verdict selects a legal target; request it |
|
|
83
|
+
| VERIFICATION | ec-verification | hard gate: lint/typecheck/test + coverage | result selects MEMORY or IMPLEMENT; request it |
|
|
84
|
+
| MEMORY | ec-memory | write short memory, then run the conditional long-memory gate | memory work complete; request COMPLETE |
|
|
85
|
+
| COMPLETE | ec-workflow | clear current_task, set task status, summary | terminal after user confirms entry |
|
|
89
86
|
| CLOSED | ec-task-close | user abort; no memory flow | terminal |
|
|
90
87
|
|
|
91
88
|
> **INIT delivery-form rule.** When creating the task, `type` and `title` must faithfully
|
|
@@ -111,14 +108,31 @@ routing matches, and switching happens again.
|
|
|
111
108
|
## Transition rules (hard)
|
|
112
109
|
|
|
113
110
|
- **Never skip a stage.** ANALYSIS cannot jump to VERIFICATION; IMPLEMENT cannot start before
|
|
114
|
-
|
|
115
|
-
not skipped ones.
|
|
116
|
-
- **
|
|
117
|
-
|
|
118
|
-
|
|
111
|
+
the ANALYSIS -> IMPLEMENT confirmation gate passes. No exception for "simple" tasks —
|
|
112
|
+
simple tasks have short analyses, not skipped ones.
|
|
113
|
+
- **Every stage edge is a confirmation gate by default.** Stage completion does NOT change
|
|
114
|
+
`task.json.status`. It records a `pending_transition` through the state API, presents the
|
|
115
|
+
standard choices below, and stops. This applies to forward edges, repair/replan edges, and
|
|
116
|
+
MEMORY -> COMPLETE. Task creation entering INIT and the separately confirmed ec-task-close
|
|
117
|
+
flow do not add a redundant second prompt.
|
|
118
|
+
- **Native choice first (hard requirement).** After `request-transition` succeeds, you MUST
|
|
119
|
+
prefer the agent/platform's native user-choice tool whenever one is available. Do not render
|
|
120
|
+
a plain-text numbered list on a platform that can present selectable options and a free-form
|
|
121
|
+
Other input. Offer exactly these business branches through that native UI:
|
|
122
|
+
1. Confirm entering/returning to `<target-stage>` (recommended)
|
|
123
|
+
2. Hand off to another agent
|
|
124
|
+
3. Other — use the native tool's built-in free-form Other input.
|
|
125
|
+
Plain-text numbered choices are fallback only: use them only when no native user-choice tool
|
|
126
|
+
exists. The runtime hook never mutates workflow state from user-prompt text. Native choice
|
|
127
|
+
results, numbered fallback replies, and every natural-language reply must be interpreted by
|
|
128
|
+
you against the current task and stored target before calling `confirm-transition` explicitly.
|
|
129
|
+
On Other feedback, cancel the pending edge before revising work or requesting a different
|
|
130
|
+
legal target. Never interpret silence, enthusiasm, or topic changes as confirmation.
|
|
131
|
+
- **State before action.** Every confirmed stage advance is a two-step protocol: first consume
|
|
132
|
+
the pending edge through `confirm-transition`, then run that stage's real work. Do not start
|
|
133
|
+
analysis, implementation, review, verification, memory writing, or closeout while
|
|
119
134
|
`task.json.status` still names the previous stage. After every state API call, treat the
|
|
120
|
-
returned snapshot/read-after-write state as authoritative for the next action and
|
|
121
|
-
status line.
|
|
135
|
+
returned snapshot/read-after-write state as authoritative for the next action and status line.
|
|
122
136
|
- **ANALYSIS entry gate.** When entering ANALYSIS, your FIRST TWO tool calls must be:
|
|
123
137
|
(1) Read `.easy-coding/templates/dev-spec-skeleton.md`, then (2) Write its exact content
|
|
124
138
|
to the task's dev-spec.md. This is a mechanical copy, not a generation task. Do not read
|
|
@@ -128,51 +142,45 @@ routing matches, and switching happens again.
|
|
|
128
142
|
Additionally, ANALYSIS must stay faithful to the user's delivery form — it may NOT downgrade
|
|
129
143
|
a code task to a report-only task — and the 改动范围 table must list only real project code,
|
|
130
144
|
never `.easy-coding/` harness artifacts (ec-analysis HARD RULES 5 and 6).
|
|
131
|
-
- **
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
- **On
|
|
142
|
-
`{{PYTHON_CMD}} {{platform_config_dir}}/hooks/easy_coding_state.py transition --session-file <P> --
|
|
145
|
+
- **Autonomous exception.** `behavior.auto_mode: true` in `.easy-coding/config.yaml` only
|
|
146
|
+
waives stage-boundary prompts when the user explicitly requested autonomous execution.
|
|
147
|
+
It carries NO scope or delivery-form decision. Never cite `auto_mode` to narrow scope,
|
|
148
|
+
downgrade a code task, or bypass a blocker that needs a real user decision.
|
|
149
|
+
- **At stage completion** request the legal target immediately (not at turn end):
|
|
150
|
+
`{{PYTHON_CMD}} {{platform_config_dir}}/hooks/easy_coding_state.py request-transition --session-file <P> --stage <STAGE> --agent <agent-id> --reason "<why this edge is ready>"`.
|
|
151
|
+
This writes only `pending_transition`; it does not change the stage.
|
|
152
|
+
- **On user confirmation** read the current task's pending edge and call:
|
|
153
|
+
`{{PYTHON_CMD}} {{platform_config_dir}}/hooks/easy_coding_state.py confirm-transition --session-file <P> --stage <STAGE> --agent <agent-id>`.
|
|
154
|
+
Only after the read-after-write status names the target stage may its action start.
|
|
155
|
+
- **On Other feedback or a changed outcome** call:
|
|
156
|
+
`{{PYTHON_CMD}} {{platform_config_dir}}/hooks/easy_coding_state.py cancel-transition --session-file <P> --agent <agent-id>`
|
|
157
|
+
before revising the current stage or requesting a different target.
|
|
143
158
|
Do not hand-edit `status`, `stage_history`, `last_agent`, `current_task`, or session files.
|
|
144
159
|
The command returns `status_line` and `status_context`; after any state-changing command,
|
|
145
160
|
discard older hook-injected status text and use this returned context as the authoritative
|
|
146
161
|
status source for the rest of the current turn.
|
|
147
|
-
If the target stage is already present because a hook preflight completed it, do not issue a
|
|
148
|
-
duplicate transition; use the latest snapshot and continue with the target stage's action.
|
|
149
162
|
- **Hook enforcement.** The `inject-workflow-state` hook validates every stage transition
|
|
150
163
|
against the state machine. If you see `[ILLEGAL-TRANSITION:...]` in the injected context,
|
|
151
164
|
you MUST revert the task's status to the previous valid stage and explain why the
|
|
152
165
|
transition was rejected. Do not proceed with an illegal stage.
|
|
153
|
-
- **Repair loop sizing** (
|
|
154
|
-
|
|
155
|
-
|
|
166
|
+
- **Repair loop sizing** (after VERIFICATION): a trivial tweak may be fixed inside
|
|
167
|
+
VERIFICATION and re-verified without a status change; a logic or structure change requests
|
|
168
|
+
VERIFICATION -> IMPLEMENT and waits at the standard confirmation gate before re-walking
|
|
169
|
+
REVIEW -> VERIFICATION.
|
|
156
170
|
- **Scope guard** (repair loop): if the user's fix request falls outside the dev-spec scope
|
|
157
171
|
(features or files absent from the change-scope table), say so explicitly and propose a
|
|
158
172
|
new task with `spawned_from` set to the current task id. Never silently absorb scope creep.
|
|
159
173
|
- **Task switching is allowed at any stage.** The suspended task retains its stage in
|
|
160
174
|
task.json. Do not run memory flows for suspended tasks — only completed tasks get archived.
|
|
161
175
|
- **Archive only after user acceptance.** VERIFICATION passing does not complete the task.
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
`memory_long` object as authoritative: `action == "no-op"` advances to COMPLETE without
|
|
171
|
-
reading or writing long memory; `action == "distill"` runs distillation for `trim_count`
|
|
172
|
-
older short-memory entries.
|
|
173
|
-
- **COMPLETE closeout:** call the state API with `--stage COMPLETE`. The state API clears
|
|
174
|
-
session `current_task` for terminal tasks, so the next hook injection returns to Ready.
|
|
175
|
-
Then output a summary (what was done, files changed, key decisions).
|
|
176
|
+
A green gate requests VERIFICATION -> MEMORY and presents the standard choices. After the
|
|
177
|
+
user confirms, MEMORY writes one short entry first, records it through `memory-short-complete`,
|
|
178
|
+
then asks the state API for the authoritative `memory` instruction. `action == "no-op"`
|
|
179
|
+
skips long-memory reads/writes; `action == "distill"` processes exactly `trim_count` older
|
|
180
|
+
entries. Only after `memory-complete` may ec-memory request MEMORY -> COMPLETE.
|
|
181
|
+
- **COMPLETE closeout:** COMPLETE is also a confirmed edge. Once the user confirms it, the
|
|
182
|
+
state API clears session `current_task`, so the next hook injection returns to Ready. Then
|
|
183
|
+
output a summary (what was done, files changed, key decisions).
|
|
176
184
|
|
|
177
185
|
## Resume and handoff
|
|
178
186
|
|
|
@@ -186,16 +194,15 @@ Resuming an active task (whether from session restart, claim, handoff, or task s
|
|
|
186
194
|
records tell you exactly where work stopped.
|
|
187
195
|
3. If the task was claimed from another agent, read the latest `handoff` record first for the
|
|
188
196
|
fast summary and tell the user which previous agent handed it off.
|
|
189
|
-
4.
|
|
197
|
+
4. If `pending_transition` exists, do not rerun the completed stage action. Re-present the
|
|
198
|
+
standard confirmation/handoff/Other choices for its stored target.
|
|
199
|
+
5. Otherwise tell the user what is being resumed and from which stage, then continue.
|
|
190
200
|
|
|
191
201
|
After a task switch, the same resume flow applies — the only difference is that `current_task`
|
|
192
202
|
was just changed by the switching procedure rather than being loaded from a prior session.
|
|
193
203
|
|
|
194
|
-
Offering handoff —
|
|
195
|
-
|
|
196
|
-
2. Write handoff and stop
|
|
197
|
-
3. Revise the plan
|
|
198
|
-
On option 2, call:
|
|
204
|
+
Offering handoff — every pending stage edge includes the standard handoff option. On that
|
|
205
|
+
option, call:
|
|
199
206
|
`{{PYTHON_CMD}} {{platform_config_dir}}/hooks/easy_coding_state.py handoff-task --session-file <P> --agent <agent-id> --summary "<dense context: plan shape, key decisions, user emphases>"`.
|
|
200
207
|
|
|
201
208
|
The handoff record is target-less:
|
|
@@ -204,8 +211,9 @@ It records who handed the task off, not who will take it next. Do not ask the us
|
|
|
204
211
|
the next agent, and do not invent or store a next-agent field. After writing handoff, stop
|
|
205
212
|
owning the task; another agent can use ec-task-management or ec-workflow to claim it.
|
|
206
213
|
|
|
207
|
-
Handoff
|
|
208
|
-
agents by itself; the next agent
|
|
214
|
+
Handoff preserves `pending_transition`, so the next agent resumes the same completed boundary
|
|
215
|
+
without rerunning stage work. The harness never switches agents by itself; the next agent
|
|
216
|
+
claims the task explicitly.
|
|
209
217
|
|
|
210
218
|
## Status line
|
|
211
219
|
|
|
@@ -35,16 +35,20 @@ First run `ec-init`; daily work goes through `ec-workflow`.
|
|
|
35
35
|
|
|
36
36
|
## Workflow discipline
|
|
37
37
|
|
|
38
|
-
- Stages do not skip.
|
|
39
|
-
|
|
38
|
+
- Stages do not skip. Every legal stage edge uses `pending_transition` and requires explicit
|
|
39
|
+
user confirmation by default. At each boundary, use the agent's native user-choice tool
|
|
40
|
+
whenever available to offer: confirm target stage, hand off to another agent, or its
|
|
41
|
+
free-form Other input. Plain-text numbered choices are fallback only. `auto_mode` only
|
|
42
|
+
waives prompts when configured and explicitly requested by the user; it never changes scope
|
|
43
|
+
or delivery form.
|
|
40
44
|
- ANALYSIS must follow template-first: read `.easy-coding/templates/dev-spec-skeleton.md` then
|
|
41
45
|
write its exact content to the task's dev-spec.md as the FIRST tool calls, then fill sections
|
|
42
46
|
incrementally via edits. Reply to the user with the complete dev-spec.md content — never a
|
|
43
47
|
summary table or custom format.
|
|
44
48
|
- VERIFICATION is a hard gate: lint + typecheck + test must pass on fresh evidence, and
|
|
45
49
|
coverage must match the test strategy, before a task can complete.
|
|
46
|
-
-
|
|
47
|
-
memory is dirty data.
|
|
50
|
+
- MEMORY combines short-memory creation and the conditional long-memory gate. Archive runs
|
|
51
|
+
only after explicit user acceptance — an unaccepted task's memory is dirty data.
|
|
48
52
|
- NO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE.
|
|
49
53
|
- All cross-platform modules (skills, hooks, references) must use universal agent protocols.
|
|
50
54
|
Do not rely on any specific agent's proprietary conventions unless the module is explicitly
|
|
@@ -54,8 +58,8 @@ First run `ec-init`; daily work goes through `ec-workflow`.
|
|
|
54
58
|
## Runtime contract
|
|
55
59
|
|
|
56
60
|
- Workflow state operations go through `{{platform_config_dir}}/hooks/easy_coding_state.py`;
|
|
57
|
-
do not hand-edit session files, `current_task`, task `status`, `stage_history`,
|
|
58
|
-
`last_agent`.
|
|
61
|
+
do not hand-edit session files, `current_task`, task `status`, `stage_history`,
|
|
62
|
+
`pending_transition`, `memory_progress`, or `last_agent`.
|
|
59
63
|
- The hook injects `[easy-coding:session-file:P]`; pass that path to the state script with
|
|
60
64
|
`--session-file <P>` when changing the current task or stage.
|
|
61
65
|
- Workflow session files live at `{{workflow_state_path}}`; the CLI only installs files and
|