easy-coding-harness 1.1.0-beta.0 → 1.1.0-beta.2

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.
@@ -12,8 +12,9 @@ user's language.
12
12
 
13
13
  ```text
14
14
  INIT --auto--> ANALYSIS -> IMPLEMENT -> QUALITY -> MEMORY --auto--> COMPLETE
15
- ^ ^ |
16
- +--replan---+ +---repair-----+
15
+ ^ |
16
+ +---- scope/contract replan -----+
17
+ QUALITY -- bounded repair --> QUALITY
17
18
 
18
19
  any active stage --explicit user abort--> CLOSED
19
20
  ```
@@ -27,23 +28,24 @@ Pure conversation, explanation, analysis, and read-only review stay Ready and cr
27
28
  - `approval_mode = approve|guard|confirm|auto` controls whether a legal transition waits for a
28
29
  user. `confirm` waits only at ANALYSIS -> IMPLEMENT; after that, green QUALITY, MEMORY, and
29
30
  COMPLETE transitions advance automatically. `auto` advances every legal green
30
- edge. The only additional pause is an exceptional code diff detected after the frozen
31
+ edge. Dispatch keeps its explicit scope/executor decision; another pause is an exceptional code diff detected after the frozen
31
32
  QUALITY acceptance checkpoint; accepting that exact diff does not change the mode.
32
33
  - `workflow_mode = adaptive|fast|standard|strict` controls execution cost and assurance depth.
33
- - `tdd_enabled` independently activates Java TDD and changed-line coverage. It defaults off;
34
- `tdd_coverage_threshold` defaults to 90 and accepts integers from 1 to 100.
34
+ - `unit_test_mode` independently selects `none`, `ut`, or `tdd`. It defaults to `none`;
35
+ `ut_coverage_threshold` defaults to 90 and accepts integers from 1 to 100.
35
36
 
36
- Approval and TDD retain session-over-project precedence. Execution depth is always the
37
+ Approval, cooperation and unit test settings use session > local > project > defaults, per field.
38
+ Local preferences live in optional `~/.easy-coding/config.yaml`; reads never create it. Execution depth is always the
37
39
  mechanically calculated minimum for the current change. Do not recommend, select a higher mode,
38
40
  or inherit an old task mode. Persist it once with `propose-workflow-mode --agent <agent-id>
39
41
  --session-file <P>`; the runtime calculates and freezes the value.
40
42
 
41
- TDD resolves with the same session-over-project precedence and freezes its enabled flag and
42
- threshold on ANALYSIS -> IMPLEMENT. It may be enabled only after `ec-tdd-init` readiness passes;
43
- there is no enabled-but-pending-initialization state. A dedicated `tdd-init` task always freezes
44
- TDD off so it can create or repair the required infrastructure without circular gating. When off,
45
- ordinary tasks add no CI scan, artifacts, commands, coverage work, or stronger acceptance. Use
46
- `ec-config` for all mode configuration.
43
+ Unit test strategy uses the same three-scope precedence and freezes its mode and
44
+ `ut_coverage_threshold` on ANALYSIS -> IMPLEMENT. UT and TDD share passed local unit tests and
45
+ changed-line coverage, and reuse `ec-tdd-init` readiness. Only TDD requires test-first lifecycle
46
+ and its review dimension. UT keeps ordinary review and compact Fast planning. The `tdd-init`
47
+ task itself freezes strategy `none`; `none` adds no infrastructure scan or coverage gate.
48
+ Both strategies reuse input-bound results and do not raise workflow depth.
47
49
 
48
50
  `confirm` and `auto` do not hide the proposal: show it in the plan. Confirm waits for that one
49
51
  plan decision; Auto continues immediately. Both remove later waiting, not quality gates.
@@ -126,7 +128,7 @@ or `qoder`. Never use a display or source-author attribution such as `Codex with
126
128
  `type=tdd-init` code task only after scope confirmation. Do not reinterpret it as an ordinary
127
129
  TDD-enabled feature task and do not require readiness before creating it.
128
130
  5. Match the user's intent against `current_task` and the active task list before resuming.
129
- If the user names or clearly matches another task, confirm the switch and call
131
+ If the user explicitly selects another task, that selection authorizes the switch; call
130
132
  `claim-task --task-id <id> --agent <agent-id> --session-file <P>`. Do not execute task A
131
133
  under task B's request.
132
134
  - With no explicit repository-mutation request, stay Ready and answer normally. Ambiguous
@@ -139,7 +141,23 @@ or `qoder`. Never use a display or source-author attribution such as `Codex with
139
141
  6. Resume the matched/current task, then load only state-relevant assets. Do not read five full
140
142
  memories at every startup; ANALYSIS searches memory metadata and opens relevant entries on
141
143
  demand.
142
- 7. If another Agent last owned the task, summarize the stored handoff before continuing.
144
+ 7. Honor the returned `continuation` before generic stage dispatch. Summarize the existing handoff,
145
+ consume its approved scope and references, and stop at `stop_after`. Never create a new task,
146
+ replan, or ask again to approve already accepted work merely because the Agent changed.
147
+ `cooperation.coordinator` stays the main Agent/session while `last_agent` tracks the executor.
148
+ A repeated claim of the same active task does not require another claim record.
149
+
150
+ ## Manual dispatch
151
+
152
+ `cooperate_mode=default` preserves handoff at stage boundaries. `dispatch` also supports handing
153
+ a QUALITY repair to another Agent without changing stage. The user manually switches Agents.
154
+ At an implementation decision, offer current-Agent execution, handoff, or defer/change once.
155
+ "Confirm and hand off" consumes the existing pending stage approval before writing a handoff;
156
+ "handoff for analysis" alone does not approve implementation. Do not ask again on claim.
157
+ Use `handoff-task --continuation` with `next_action`, existing `unit_ids`, optional `evidence_refs`,
158
+ and `stop_after`. Implement-only handoff uses `next_action:implement, stop_after:IMPLEMENT`;
159
+ on completion return `next_action:quality` to the coordinator. QUALITY repairs follow ec-quality.
160
+ The user can authorize the coordinator to fix a small change directly in either mode.
143
161
 
144
162
  ## Stage dispatch
145
163
 
@@ -158,7 +176,8 @@ clears the pending action so the corrected action can proceed; never overwrite a
158
176
  pending action.
159
177
 
160
178
  Creation and claim return `spec_context.consumption` for the stored selection. Consume it before
161
- dispatching a stage. After session resume or design sync, call `resume-spec-context --agent
179
+ dispatching a stage. Reuse a matching current-session receipt (`spec_context.reused:true`) and context already loaded.
180
+ If context was lost, the session is new, or design changed, call `resume-spec-context --agent
162
181
  <agent-id> --session-file <P>` and consume its returned closure. A blocked context requires
163
182
  source repair or design sync; never continue from a handoff summary alone. If `spec_change` is
164
183
  pending, resume that confirmed change on the bound original file before implementation/QUALITY.
@@ -211,8 +230,9 @@ acceptance-diff choice and returns to the stage required by the state API.
211
230
  For an explicitly confirmed rollback, scope reduction, or bounded correction of an active task,
212
231
  call `begin-correction --file <existing-task-file> ... --summary <confirmed-change>
213
232
  [--risk <actual-new-risk>] --agent <agent-id> --session-file <P>`. The runtime preserves the plan,
214
- unaffected Units and evidence, consumes old QUALITY state, and enters IMPLEMENT at the mechanical
215
- minimum for these files. Do not reconstruct the original task or its documents. Synchronize only
233
+ unaffected Units and evidence. In QUALITY it prepares an in-stage repair bundle; use
234
+ `start-quality-repair` and `complete-quality-repair` without a stage transition. Other active stages
235
+ use IMPLEMENT at the mechanical minimum for these files. Do not reconstruct the original task or its documents. Synchronize only
216
236
  conflicting source Spec clauses once when needed; then continue the correction. Never restore an
217
237
  entire file over unrelated user edits. A new feature or expanded contract still needs ANALYSIS.
218
238
 
@@ -12,9 +12,9 @@ Start every work reply with the single Markdown blockquote status line injected
12
12
  then a blank line. Do not render the machine breadcrumbs to the user.
13
13
 
14
14
  `{approval-mode}` is the effective approval mode and `{workflow-mode}` is the configured or
15
- task-frozen execution mode; session overrides take precedence over project settings.
16
- When effective/frozen TDD is enabled, insert `· **TDD**` immediately after Workflow. When it is
17
- disabled, omit the TDD segment entirely and preserve the existing status-line format.
15
+ task-frozen execution mode; behavior settings resolve per field: session > optional local ~/.easy-coding/config.yaml > project > defaults.
16
+ When effective/frozen unit_test_mode is `ut` or `tdd`, insert `· **UT**` or **TDD**`
17
+ immediately after Workflow. For `none`, omit this segment and preserve the status-line format.
18
18
 
19
19
  - Ready: > **Easy Coding** · **Approval: {approval-mode}** · **Workflow: {workflow-mode}** · Ready · Use `ec-workflow` to start or resume a task, `ec-brainstorming` to brainstorm, `ec-task-management` to manage tasks, or `ec-config` to inspect or change modes
20
20
  - Waiting init: > **Easy Coding** · **Approval: {approval-mode}** · **Workflow: {workflow-mode}** · Waiting init · Use `ec-init` to initialize
@@ -34,7 +34,7 @@ Trigger Easy Coding skills with your platform prefix — Codex: `$ec-*`, Qoder:
34
34
  - `ec-brainstorming` — design exploration before building (hard design gate)
35
35
  - `ec-analysis` `ec-implementing` `ec-quality` — workflow stages
36
36
  - `ec-memory` — short/long memory archive
37
- - `ec-task-management` — task lifecycle panel · `ec-config` — Approval/Workflow/TDD settings · `ec-tdd-init` — Java changed-line gate initialization · `ec-task-close` — interrupt a task
37
+ - `ec-task-management` — task lifecycle panel · `ec-config` — Approval/Workflow/unit-test settings · `ec-tdd-init` — Java changed-line gate initialization · `ec-task-close` — interrupt a task
38
38
  - `ec-no-harness` — bypass only Easy Coding for the current session
39
39
  - `ec-lite` — user-controlled direct mode with one proposal confirmation and no task/QUALITY/MEMORY
40
40
  - `ec-git` — git discipline · `ec-meta` — understand/customize the harness
@@ -43,25 +43,27 @@ First run `ec-init`; daily work goes through `ec-workflow`.
43
43
 
44
44
  ## Workflow discipline
45
45
 
46
- - Approval mode is session override > project `behavior.approval_mode` > `guard`; workflow mode
46
+ - Approval mode is session override > local ~/.easy-coding/config.yaml > project `behavior.approval_mode` > `guard`; workflow mode
47
47
  is the mechanical minimum for the current actual change. Approval controls waiting;
48
48
  workflow controls execution depth. Do not recommend or inflate the calculated mode.
49
49
  Confirm approval waits only at ANALYSIS -> IMPLEMENT, then advances green later stages
50
- automatically; Auto advances all legal green edges. A new code diff after the QUALITY
51
- checkpoint is the only exceptional pause across all modes: show the exact diff, bind acceptance
50
+ automatically; Auto advances all legal green edges. Dispatch retains the explicit scope/executor
51
+ decision, merged with any required approval. A new code diff after the QUALITY
52
+ checkpoint also pauses across all modes: show the exact diff, bind acceptance
52
53
  to its digest, and continue without rereview when the user accepts.
53
54
  Every mutation task runs QUALITY; no mode changes scope, delivery form, or evidence gates.
54
- - TDD is session override > project `behavior.tdd_enabled` > `false`; its changed-line threshold
55
- is session override > project `behavior.tdd_coverage_threshold` > `90`. ANALYSIS -> IMPLEMENT
56
- freezes both. TDD may be enabled only after `ec-tdd-init` records valid infrastructure readiness;
57
- build version/content changes require fresh task evidence, not reinitialization. Repair missing
58
- local entries without resetting TDD; CLI upgrades preserve project/session/frozen task settings;
59
- there is no enable-now/init-later state. The dedicated `tdd-init` task always freezes TDD off and
60
- initializes only changed-line coverage infrastructure, never historical business-test coverage.
61
- Disabled TDD adds no CI scan, JaCoCo work, commands, artifacts, or stronger gates. Enabled TDD
62
- applies only to Java code tasks and requires lifecycle, review, passed local unit tests, and
63
- local coverage for production lines changed since the task baseline. `ec-tdd-init` still
64
- generates GitLab TEST-stage automation, but remote CI status is not Harness acceptance evidence.
55
+ - Unit test strategy is session override > local ~/.easy-coding/config.yaml > project `behavior.unit_test_mode` > `none`.
56
+ Values are `none`, `ut`, and `tdd`; both enabled strategies share `ut_coverage_threshold`
57
+ (session > local > project > 90, integer 1..100). ANALYSIS -> IMPLEMENT freezes strategy, threshold,
58
+ and repository baselines. `none` adds no coverage work and retains ordinary task verification.
59
+ UT requires passed local unit tests and changed-production-line coverage, without test-first
60
+ ordering, RED/GREEN artifacts, or a separate TDD review. TDD additionally requires its lifecycle
61
+ and review dimension. Assertions remain part of ordinary review in UT.
62
+ Both currently support Java and reuse `ec-tdd-init` readiness, JaCoCo, and existing evidence
63
+ reuse. One test execution supplies tests plus coverage. No new stages or workflow escalation.
64
+ The dedicated `tdd-init` task freezes strategy `none`; readiness failure reports repair rather
65
+ than resetting configuration. CLI upgrades migrate old fields and preserve frozen task progress.
66
+ GitLab automation is infrastructure, not remote acceptance evidence.
65
67
  - Confirmation-required edges use `pending_transition`; automatic edges use the restricted
66
68
  `auto-transition` API. Pure read-only conversation stays Ready and creates no task. Any
67
69
  repository write, including documentation or configuration, uses the full state machine.
@@ -112,7 +114,7 @@ First run `ec-init`; daily work goes through `ec-workflow`.
112
114
  Runtime progress must use the shared writer with CAS/idempotency and reconciliation; static
113
115
  confirmed design changes first use `begin-spec-change`, then revision + READY + `sync-spec-design`.
114
116
  Creation/claim returns selected source context; session resume and design sync require
115
- `resume-spec-context` before work. Pending changes block implementation/acceptance across agents.
117
+ `resume-spec-context` only when current-session context is missing or design changed; otherwise reuse it. Pending changes block implementation/acceptance across agents.
116
118
  Preserve the original writer actor while retaining the current owner during reconciliation.
117
119
  Never hand-edit `EDS:EXECUTION`.
118
120
  Selected source tasks remain `implemented` through local QUALITY and become `verified`
@@ -165,3 +167,19 @@ speculative fallback/retry/compatibility logic, or defensive copying.
165
167
 
166
168
  Add project-specific instructions below this line. The generated region above is managed by
167
169
  easy-coding-harness and is replaced on `easy-coding upgrade`.
170
+
171
+ ## Cooperation and bounded QUALITY repair
172
+
173
+ `cooperate_mode: default | dispatch` is independent of approval and unit-test strategy, with
174
+ session > optional local `~/.easy-coding/config.yaml` > project > default precedence. Reads never
175
+ create local config; ec-config changes only explicitly selected fields and can restore inheritance.
176
+ Default preserves stage-boundary handoff. Dispatch supports manual implementation and QUALITY
177
+ repair handoff; the user can always select current-Agent execution. Preserve the task coordinator,
178
+ use existing plan/evidence references and stop at the handoff's `stop_after`. Never launch another Agent.
179
+ Dispatch requires one user decision on scope and executor, even under Auto; combine any approval
180
+ with that same decision and never ask again on claim. Ordinary repairs stay in QUALITY using
181
+ begin-correction, start-quality-repair and complete-quality-repair. Only changed requirements,
182
+ contracts or a replaced main implementation plan justify returning to ANALYSIS/IMPLEMENT.
183
+ Review and verification remain read-only checks; approved repairs happen between them. Reuse
184
+ unaffected evidence, review the repair delta and run affected checks only. Do not rebuild the plan
185
+ or repeat completed checks because of handoff, stage labels or descriptive check-name changes.
@@ -12,9 +12,9 @@ Start every work reply with the single Markdown blockquote status line injected
12
12
  then a blank line. Do not render the machine breadcrumbs to the user.
13
13
 
14
14
  `{approval-mode}` is the effective approval mode and `{workflow-mode}` is the configured or
15
- task-frozen execution mode; session overrides take precedence over project settings.
16
- When effective/frozen TDD is enabled, insert `· **TDD**` immediately after Workflow. When it is
17
- disabled, omit the TDD segment entirely and preserve the existing status-line format.
15
+ task-frozen execution mode; behavior settings resolve per field: session > optional local ~/.easy-coding/config.yaml > project > defaults.
16
+ When effective/frozen unit_test_mode is `ut` or `tdd`, insert `· **UT**` or **TDD**`
17
+ immediately after Workflow. For `none`, omit this segment and preserve the status-line format.
18
18
 
19
19
  - Ready: > **Easy Coding** · **Approval: {approval-mode}** · **Workflow: {workflow-mode}** · Ready · Use `ec-workflow` to start or resume a task, `ec-brainstorming` to brainstorm, `ec-task-management` to manage tasks, or `ec-config` to inspect or change modes
20
20
  - Waiting init: > **Easy Coding** · **Approval: {approval-mode}** · **Workflow: {workflow-mode}** · Waiting init · Use `ec-init` to initialize
@@ -32,7 +32,7 @@ platform prefixes such as `/` or `$`. If no status line is injected, do not inve
32
32
  - `/ec-brainstorming` — design exploration before building (hard design gate)
33
33
  - `/ec-analysis` `/ec-implementing` `/ec-quality` — workflow stages
34
34
  - `/ec-memory` — short/long memory archive
35
- - `/ec-task-management` — task lifecycle panel · `/ec-config` — Approval/Workflow/TDD settings · `/ec-tdd-init` — Java changed-line gate initialization · `/ec-task-close` — interrupt a task
35
+ - `/ec-task-management` — task lifecycle panel · `/ec-config` — Approval/Workflow/unit-test settings · `/ec-tdd-init` — Java changed-line gate initialization · `/ec-task-close` — interrupt a task
36
36
  - `/ec-no-harness` — bypass only Easy Coding for the current session
37
37
  - `/ec-lite` — user-controlled direct mode with one proposal confirmation and no task/QUALITY/MEMORY
38
38
  - `/ec-git` — git discipline · `/ec-meta` — understand/customize the harness
@@ -41,25 +41,27 @@ First run `/ec-init`; daily work goes through `/ec-workflow`.
41
41
 
42
42
  ## Workflow discipline
43
43
 
44
- - Approval mode is session override > project `behavior.approval_mode` > `guard`; workflow mode
44
+ - Approval mode is session override > local ~/.easy-coding/config.yaml > project `behavior.approval_mode` > `guard`; workflow mode
45
45
  is the mechanical minimum for the current actual change. Approval controls waiting;
46
46
  workflow controls execution depth. Do not recommend or inflate the calculated mode.
47
47
  Confirm approval waits only at ANALYSIS -> IMPLEMENT, then advances green later stages
48
- automatically; Auto advances all legal green edges. A new code diff after the QUALITY
49
- checkpoint is the only exceptional pause across all modes: show the exact diff, bind acceptance
48
+ automatically; Auto advances all legal green edges. Dispatch retains the explicit scope/executor
49
+ decision, merged with any required approval. A new code diff after the QUALITY
50
+ checkpoint also pauses across all modes: show the exact diff, bind acceptance
50
51
  to its digest, and continue without rereview when the user accepts.
51
52
  Every mutation task runs QUALITY; no mode changes scope, delivery form, or evidence gates.
52
- - TDD is session override > project `behavior.tdd_enabled` > `false`; its changed-line threshold
53
- is session override > project `behavior.tdd_coverage_threshold` > `90`. ANALYSIS -> IMPLEMENT
54
- freezes both. TDD may be enabled only after `ec-tdd-init` records valid infrastructure readiness;
55
- build version/content changes require fresh task evidence, not reinitialization. Repair missing
56
- local entries without resetting TDD; CLI upgrades preserve project/session/frozen task settings;
57
- there is no enable-now/init-later state. The dedicated `tdd-init` task always freezes TDD off and
58
- initializes only changed-line coverage infrastructure, never historical business-test coverage.
59
- Disabled TDD adds no CI scan, JaCoCo work, commands, artifacts, or stronger gates. Enabled TDD
60
- applies only to Java code tasks and requires lifecycle, review, passed local unit tests, and
61
- local coverage for production lines changed since the task baseline. `ec-tdd-init` still
62
- generates GitLab TEST-stage automation, but remote CI status is not Harness acceptance evidence.
53
+ - Unit test strategy is session override > local ~/.easy-coding/config.yaml > project `behavior.unit_test_mode` > `none`.
54
+ Values are `none`, `ut`, and `tdd`; both enabled strategies share `ut_coverage_threshold`
55
+ (session > local > project > 90, integer 1..100). ANALYSIS -> IMPLEMENT freezes strategy, threshold,
56
+ and repository baselines. `none` adds no coverage work and retains ordinary task verification.
57
+ UT requires passed local unit tests and changed-production-line coverage, without test-first
58
+ ordering, RED/GREEN artifacts, or a separate TDD review. TDD additionally requires its lifecycle
59
+ and review dimension. Assertions remain part of ordinary review in UT.
60
+ Both currently support Java and reuse `ec-tdd-init` readiness, JaCoCo, and existing evidence
61
+ reuse. One test execution supplies tests plus coverage. No new stages or workflow escalation.
62
+ The dedicated `tdd-init` task freezes strategy `none`; readiness failure reports repair rather
63
+ than resetting configuration. CLI upgrades migrate old fields and preserve frozen task progress.
64
+ GitLab automation is infrastructure, not remote acceptance evidence.
63
65
  - Confirmation-required edges use `pending_transition`; automatic edges use the restricted
64
66
  `auto-transition` API. Pure read-only conversation stays Ready and creates no task. Any
65
67
  repository write, including documentation or configuration, uses the full state machine.
@@ -110,7 +112,7 @@ First run `/ec-init`; daily work goes through `/ec-workflow`.
110
112
  Runtime progress must use the shared writer with CAS/idempotency and reconciliation; static
111
113
  confirmed design changes first use `begin-spec-change`, then revision + READY + `sync-spec-design`.
112
114
  Creation/claim returns selected source context; session resume and design sync require
113
- `resume-spec-context` before work. Pending changes block implementation/acceptance across agents.
115
+ `resume-spec-context` only when current-session context is missing or design changed; otherwise reuse it. Pending changes block implementation/acceptance across agents.
114
116
  Preserve the original writer actor while retaining the current owner during reconciliation.
115
117
  Never hand-edit `EDS:EXECUTION`.
116
118
  Selected source tasks remain `implemented` through local QUALITY and become `verified`
@@ -160,3 +162,19 @@ speculative fallback/retry/compatibility logic, or defensive copying.
160
162
 
161
163
  Add project-specific instructions below this line. The generated region above is managed by
162
164
  easy-coding-harness and is replaced on `easy-coding upgrade`.
165
+
166
+ ## Cooperation and bounded QUALITY repair
167
+
168
+ `cooperate_mode: default | dispatch` is independent of approval and unit-test strategy, with
169
+ session > optional local `~/.easy-coding/config.yaml` > project > default precedence. Reads never
170
+ create local config; ec-config changes only explicitly selected fields and can restore inheritance.
171
+ Default preserves stage-boundary handoff. Dispatch supports manual implementation and QUALITY
172
+ repair handoff; the user can always select current-Agent execution. Preserve the task coordinator,
173
+ use existing plan/evidence references and stop at the handoff's `stop_after`. Never launch another Agent.
174
+ Dispatch requires one user decision on scope and executor, even under Auto; combine any approval
175
+ with that same decision and never ask again on claim. Ordinary repairs stay in QUALITY using
176
+ begin-correction, start-quality-repair and complete-quality-repair. Only changed requirements,
177
+ contracts or a replaced main implementation plan justify returning to ANALYSIS/IMPLEMENT.
178
+ Review and verification remain read-only checks; approved repairs happen between them. Reuse
179
+ unaffected evidence, review the repair delta and run affected checks only. Do not rebuild the plan
180
+ or repeat completed checks because of handoff, stage labels or descriptive check-name changes.
@@ -191,16 +191,16 @@ def read_project_threshold(repo: Path) -> int:
191
191
  schema_version = 0
192
192
  continue
193
193
  if (
194
- schema_version >= 4
194
+ schema_version >= 6
195
195
  and in_behavior
196
- and stripped.startswith("tdd_coverage_threshold:")
196
+ and stripped.startswith("ut_coverage_threshold:")
197
197
  ):
198
198
  try:
199
199
  value = int(stripped.split(":", 1)[1].strip().strip("'\""))
200
200
  except ValueError as error:
201
- raise CoverageError("Invalid behavior.tdd_coverage_threshold") from error
201
+ raise CoverageError("Invalid behavior.ut_coverage_threshold") from error
202
202
  if not 1 <= value <= 100:
203
- raise CoverageError("TDD coverage threshold must be from 1 to 100")
203
+ raise CoverageError("Unit test coverage threshold must be from 1 to 100")
204
204
  return value
205
205
  return DEFAULT_THRESHOLD
206
206
 
@@ -294,7 +294,7 @@ def main() -> int:
294
294
  else read_project_threshold(repo)
295
295
  )
296
296
  if not 1 <= threshold <= 100:
297
- raise CoverageError("TDD coverage threshold must be from 1 to 100")
297
+ raise CoverageError("Unit test coverage threshold must be from 1 to 100")
298
298
  reports = (
299
299
  sorted({Path(item).resolve() for item in args.report})
300
300
  if args.report
@@ -40,6 +40,24 @@ def memo(key, compute):
40
40
  return cache[key]
41
41
 
42
42
 
43
+ def invalidate_memo(key):
44
+ cache = _operation.get()
45
+ if cache is not None:
46
+ cache.pop(key, None)
47
+
48
+
49
+ def cached_memo(key):
50
+ cache = _operation.get()
51
+ return cache.get(key) if cache is not None else None
52
+
53
+
54
+ def command_identity(command):
55
+ # Shell 展开和重定向受引号影响;只归一化普通 argv 命令,避免错误复用。
56
+ if re.search(r"[\$`\\\n;|&<>*?\[\]{}~#]", command):
57
+ return command
58
+ return tuple(shlex.split(command))
59
+
60
+
43
61
  def digest(value):
44
62
  return hashlib.sha256(json.dumps(value, sort_keys=True, ensure_ascii=False,
45
63
  separators=(",", ":")).encode()).hexdigest()
@@ -255,7 +273,7 @@ def input_spec(root, task, plan, check):
255
273
  "tests" if builds_module else "tests/fixtures"):
256
274
  if (base / config).is_dir():
257
275
  paths.add(config)
258
- if task.get("tdd_enabled") is True:
276
+ if task.get("unit_test_mode") in {"ut", "tdd"}:
259
277
  for directory in {str(root.resolve()), *repositories}:
260
278
  manifest = Path(directory) / ".easy-coding/tdd/readiness.json"
261
279
  if manifest.is_file():