easy-coding-harness 0.10.0-beta.2 → 0.10.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +4 -2
- package/package.json +1 -1
- package/templates/common/bundled-skills/ec-init/SKILL.md +2 -1
- package/templates/common/bundled-skills/ec-meta/references/local-architecture/README.md +3 -2
- package/templates/common/skills/ec-analysis/SKILL.md +12 -8
- package/templates/common/skills/ec-config/SKILL.md +3 -1
- package/templates/common/skills/ec-memory/SKILL.md +4 -3
- package/templates/common/skills/ec-reviewing/SKILL.md +4 -2
- package/templates/common/skills/ec-tdd-init/SKILL.md +3 -1
- package/templates/common/skills/ec-verification/SKILL.md +10 -22
- package/templates/main-constraint/AGENTS.md.tpl +3 -2
- package/templates/main-constraint/CLAUDE.md.tpl +3 -2
- package/templates/shared-hooks/easy_coding_state.py +37 -34
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,18 @@
|
|
|
6
6
|
- `y`:常规功能升级
|
|
7
7
|
- `z`:日常 bug 修复
|
|
8
8
|
|
|
9
|
+
## 0.10.0-beta.3
|
|
10
|
+
|
|
11
|
+
- TDD 业务任务的 `VERIFICATION` 门禁收口为本地证据:每个仓库(Canonical 场景下每个
|
|
12
|
+
source task)必须有通过的本地单测,以及达到冻结阈值的本地 JaCoCo changed-line
|
|
13
|
+
coverage;不再要求远程 GitLab pipeline URL、job identity 或成功状态。
|
|
14
|
+
- `ec-tdd-init` 继续在 TDD 关闭态生成并校验参数化 GitLab TEST-stage job、构建配置、
|
|
15
|
+
JaCoCo XML 与 readiness receipt,但远程 CI 只作为项目自动化能力,不再触发 Harness
|
|
16
|
+
中间提交、推送或等待远程结果。
|
|
17
|
+
- beta.1/beta.2 任务中已有的 `coverage_scope=gitlab` 记录保持原样并从新验收集合中忽略,
|
|
18
|
+
因此 pending/failed 远程记录不会阻塞升级后的本地门禁;本地 baseline、阈值、报告
|
|
19
|
+
指纹及 TDD 生命周期/review 约束保持不变。
|
|
20
|
+
|
|
9
21
|
## 0.10.0-beta.2
|
|
10
22
|
|
|
11
23
|
- 新增 `ec-tdd-init`,在 TDD 关闭态初始化或刷新 Java 单测执行、JaCoCo XML、GitLab
|
package/README.md
CHANGED
|
@@ -86,7 +86,7 @@ any stage --[user abort via ec-task-close]--> CLOSED
|
|
|
86
86
|
ANALYSIS → IMPLEMENT 确认一次,随后各阶段在质量门禁通过后自动推进,`auto` 从开始即
|
|
87
87
|
自动推进。
|
|
88
88
|
- 工作流模式优先级为 session 覆盖 > 项目 `behavior.workflow_mode` > `adaptive`。Adaptive 在 ANALYSIS 结束时根据风险解析、展示并冻结为 `fast`、`standard` 或 `strict`,用户可在风险下限之上调整。
|
|
89
|
-
- Java TDD 默认关闭;优先级为 session 覆盖 > 项目配置 > `false/90%`。首次开启前必须运行 `ec-tdd-init`,只建设 JUnit/JaCoCo/GitLab 增量覆盖率基础设施,不补存量业务单测;readiness 通过后才允许显式开启。开启后在 ANALYSIS → IMPLEMENT 冻结开关、baseline 与阈值,只验收本任务新增/修改生产代码行,执行 RED/GREEN/REFACTOR(纯重构使用 characterization GREEN → GREEN
|
|
89
|
+
- Java TDD 默认关闭;优先级为 session 覆盖 > 项目配置 > `false/90%`。首次开启前必须运行 `ec-tdd-init`,只建设 JUnit/JaCoCo/GitLab 增量覆盖率基础设施,不补存量业务单测;readiness 通过后才允许显式开启。开启后在 ANALYSIS → IMPLEMENT 冻结开关、baseline 与阈值,只验收本任务新增/修改生产代码行,执行 RED/GREEN/REFACTOR(纯重构使用 characterization GREEN → GREEN),并要求本地单测通过、本地差异覆盖率达到冻结阈值。GitLab TEST-stage job 仍会生成,但远程 pipeline 结果不属于 Harness 验收证据,也不会触发中间提交推送。关闭时普通任务不扫描 CI/JaCoCo、不增加命令或提高原工作流验收深度。
|
|
90
90
|
- 所有新代码任务都完整进入 REVIEW;不同工作流模式只调整各状态内部的上下文加载、执行主体、审查独立性、验证范围和记忆深度,不绕过状态或证据门禁。
|
|
91
91
|
- 显式 `doc` / `analysis` / `report` 只读任务不生成 `test-strategy.md`;展示完整报告后按生效模式进入 COMPLETE,不执行 REVIEW、VERIFICATION 或 MEMORY,也不写任务记忆。
|
|
92
92
|
- `VERIFICATION` 是验证硬门控:Fast 运行最小充分检查,Standard 运行受影响范围检查,
|
|
@@ -190,7 +190,9 @@ easy-coding upgrade
|
|
|
190
190
|
项目 Harness 与 CLI 版本完全一致,否则先执行 `easy-coding upgrade` 或更新 CLI);当前
|
|
191
191
|
session 临时覆盖统一通过 `ec-config` 对话修改。升级到 0.10.0-beta.2 时配置 schema 升至
|
|
192
192
|
5;未完成 `ec-tdd-init` readiness 的项目/session TDD 请求迁移为关闭并保留阈值,同时
|
|
193
|
-
部署共享 Java 差异覆盖率与 readiness
|
|
193
|
+
部署共享 Java 差异覆盖率与 readiness 工具。0.10.0-beta.3 起,TDD 业务任务只依赖本地
|
|
194
|
+
单测与本地差异覆盖率,历史远程 CI 证据保留但不再参与验收。已经冻结的活动任务合同
|
|
195
|
+
不会被静默改写。
|
|
194
196
|
|
|
195
197
|
若当前会话不希望 Harness 接管,显式调用 `/ec-no-harness`(Codex 使用
|
|
196
198
|
`$ec-no-harness`)。它只旁路 Easy Coding,不关闭其他 hooks,也不忽略其他 skills;
|
package/package.json
CHANGED
|
@@ -161,7 +161,8 @@ agent must be able to see what was generated and on what evidence.
|
|
|
161
161
|
you verified exist (read package.json scripts or equivalent — do not guess).
|
|
162
162
|
If effective TDD is disabled, do not inspect JaCoCo or GitLab and do not add TDD-specific
|
|
163
163
|
requirements. If it is enabled for Java, additionally document JUnit/JaCoCo commands,
|
|
164
|
-
production/test source roots, XML report paths,
|
|
164
|
+
production/test source roots, XML report paths, the local acceptance gate, and the generated
|
|
165
|
+
GitLab TEST-stage job as non-blocking automation infrastructure.
|
|
165
166
|
5. **Memory migration probe** — Check for old-format memory files:
|
|
166
167
|
- `.easy-coding/memory/long/MEMORY.md` exists but lacks `memory_schema: 2` frontmatter
|
|
167
168
|
- `.easy-coding/memory/long/BUSINESS.md` or `TECHNICAL.md` missing
|
|
@@ -58,8 +58,9 @@ and config fingerprints, and MEMORY keeps the conditional long-memory threshold
|
|
|
58
58
|
Java TDD is a third independent, default-off control managed by `ec-config`. Session overrides
|
|
59
59
|
project configuration; ANALYSIS freezes enabled state and the 1..100 changed-line threshold
|
|
60
60
|
(default 90) on entry to IMPLEMENT. Disabled TDD changes no ordinary workflow test depth. Enabled
|
|
61
|
-
TDD adds lifecycle evidence, a TDD review dimension,
|
|
62
|
-
GitLab TEST-stage
|
|
61
|
+
TDD adds lifecycle evidence, a TDD review dimension, passed local unit-test evidence, and a local
|
|
62
|
+
JaCoCo diff gate. `ec-tdd-init` still generates the equivalent GitLab TEST-stage job, but remote
|
|
63
|
+
pipeline execution and status are not Harness acceptance dependencies.
|
|
63
64
|
|
|
64
65
|
The active task pointer lives in `sessions/{agent}-{session-id}.json` (with an agent-prefixed PPID fallback only
|
|
65
66
|
when a hook payload has no logical session ID);
|
|
@@ -113,20 +113,24 @@ When TDD is enabled for a Java code task, make `test-strategy.md` record:
|
|
|
113
113
|
toward 100% while treating the threshold as the mechanical minimum;
|
|
114
114
|
- feature/bug RED -> GREEN -> REFACTOR evidence, or for pure refactors a pre-change
|
|
115
115
|
characterization GREEN -> post-change GREEN sequence without inventing a RED failure;
|
|
116
|
-
-
|
|
117
|
-
|
|
118
|
-
|
|
116
|
+
- the local unit-test command and local changed-line acceptance command. Record that
|
|
117
|
+
`ec-tdd-init` generated the GitLab TEST-stage job, but remote execution, pipeline identity, and
|
|
118
|
+
status are non-blocking and never require an intermediate commit or push. Include these exact,
|
|
119
|
+
language-independent contract markers: `local_test_gate: required` and
|
|
120
|
+
`remote_ci_acceptance: non-blocking`.
|
|
119
121
|
- current `tdd_readiness_status=ready`; if missing or drifted, stop before IMPLEMENT and route to
|
|
120
122
|
`ec-tdd-init`. Never plan to initialize CI inside an already-enabled TDD feature task.
|
|
121
123
|
|
|
122
124
|
The state API mechanically freezes current Git `HEAD` per repository into `task.tdd_baselines`
|
|
123
|
-
when ANALYSIS advances to IMPLEMENT. Plan
|
|
124
|
-
|
|
125
|
-
|
|
125
|
+
when ANALYSIS advances to IMPLEMENT. Plan the local command with that exact SHA and the frozen
|
|
126
|
+
threshold. The generated GitLab job remains parameterized for infrastructure parity, but the
|
|
127
|
+
Harness acceptance plan never waits for remote CI. Never use a mutable `HEAD` fallback at
|
|
128
|
+
verification time. Non-Canonical TDD is limited to one Git repository; multi-repository TDD must
|
|
129
|
+
use Canonical repository bindings.
|
|
126
130
|
|
|
127
131
|
Also append a `### TDD Mode` section to `dev-spec.md` with enabled state, frozen threshold,
|
|
128
|
-
baseline, local gate,
|
|
129
|
-
is disabled.
|
|
132
|
+
baseline, local unit-test gate, local coverage gate, generated GitLab job as non-blocking
|
|
133
|
+
infrastructure, and lifecycle evidence. Do not add this section when TDD is disabled.
|
|
130
134
|
|
|
131
135
|
If the task is not a Java project, explain that Java-only TDD cannot be activated and obtain a
|
|
132
136
|
mode decision before advancing. The CLI never installs JaCoCo or edits CI automatically.
|
|
@@ -60,7 +60,9 @@ After explicit user selection, use the current logical session file:
|
|
|
60
60
|
Turning TDD off must preserve the existing Fast/Standard/Strict test depth exactly: do not inspect
|
|
61
61
|
CI, request JaCoCo, add TDD artifacts, run coverage commands, or strengthen acceptance criteria.
|
|
62
62
|
When TDD is on, explain that it applies only to Java code tasks and activates RED/GREEN/REFACTOR,
|
|
63
|
-
TDD review, local
|
|
63
|
+
TDD review, a passed local unit-test gate, and local changed-line JaCoCo coverage. `ec-tdd-init`
|
|
64
|
+
still generates the GitLab TEST-stage job, but Harness does not wait for or record remote pipeline
|
|
65
|
+
results as acceptance evidence.
|
|
64
66
|
|
|
65
67
|
Before any project/session enable action, require `tdd_readiness_status=ready`. If it is not ready,
|
|
66
68
|
offer only `ec-tdd-init` or cancellation; never offer or persist "enable now, initialize later".
|
|
@@ -28,9 +28,10 @@ Name it `{memory_id}_{YYYYMMDD}_{smart_name}.md` and set
|
|
|
28
28
|
`.easy-coding/memory/short/`, then register it with
|
|
29
29
|
`memory-short-complete`. Never invent test results or commit hashes.
|
|
30
30
|
|
|
31
|
-
When frozen TDD is enabled, add its threshold, lifecycle evidence, local
|
|
32
|
-
and
|
|
33
|
-
|
|
31
|
+
When frozen TDD is enabled, add its threshold, lifecycle evidence, passed local unit-test result,
|
|
32
|
+
and local changed-line result to the short memory's execution evidence. Remote CI status is not
|
|
33
|
+
part of Harness acceptance or task memory. When TDD is off, omit TDD fields entirely so ordinary
|
|
34
|
+
tasks incur no additional memory work.
|
|
34
35
|
|
|
35
36
|
Ask the state API for `memory-instruction`. Distill only when it returns `action:distill`;
|
|
36
37
|
otherwise record `no-op`. Long memory receives reusable facts only, not file dumps, transient
|
|
@@ -24,8 +24,10 @@ review dimension. A global record without source ownership cannot satisfy the ga
|
|
|
24
24
|
When frozen TDD is enabled, add a passed review dimension named exactly `tdd` for each source
|
|
25
25
|
task. Review whether RED/GREEN/REFACTOR (or characterization GREEN for pure refactors) is genuine,
|
|
26
26
|
tests exercise changed behavior and boundaries, mocks do not merely mirror implementation, and
|
|
27
|
-
the local
|
|
28
|
-
|
|
27
|
+
the local unit-test command genuinely passes while the changed-line coverage command uses the
|
|
28
|
+
frozen baseline and threshold. Generated CI configuration may be reviewed when it changed, but
|
|
29
|
+
remote CI status is never a review or acceptance dependency. When TDD is off, do not add this
|
|
30
|
+
dimension or raise the ordinary review depth.
|
|
29
31
|
|
|
30
32
|
## Depth by workflow mode
|
|
31
33
|
|
|
@@ -64,7 +64,9 @@ purpose is to cover unchanged production code.
|
|
|
64
64
|
|
|
65
65
|
The reusable GitLab job must consume a baseline SHA and threshold supplied for the future task;
|
|
66
66
|
do not hardcode the initialization commit or the default 90% threshold. The same Python coverage
|
|
67
|
-
tool must be
|
|
67
|
+
tool must be usable locally and remotely. This generated job is remote automation infrastructure,
|
|
68
|
+
not a Harness task acceptance dependency: later tasks require local unit-test and coverage
|
|
69
|
+
evidence only, and never wait for a pipeline URL, job identity, or remote success status.
|
|
68
70
|
|
|
69
71
|
## Readiness receipt and verification
|
|
70
72
|
|
|
@@ -30,8 +30,8 @@ coverage tool, inspect GitLab, or add a coverage record. The explicit `type=tdd-
|
|
|
30
30
|
infrastructure exception: run its planned build/CI syntax checks and readiness tool, but do not
|
|
31
31
|
measure repository-wide coverage or append TDD coverage evidence for unchanged production code.
|
|
32
32
|
|
|
33
|
-
When frozen TDD is on, first run the planned Java unit command and generate JaCoCo XML,
|
|
34
|
-
the
|
|
33
|
+
When frozen TDD is on, first run the planned local Java unit command and generate JaCoCo XML,
|
|
34
|
+
then run the deterministic local acceptance gate:
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
37
|
python3 .easy-coding/tools/easy_coding_java_coverage.py check \
|
|
@@ -43,10 +43,10 @@ The tool measures covered added/modified production Java executable lines only.
|
|
|
43
43
|
comment, blank, import, and test-source lines are excluded by diff/JaCoCo intersection. Missing
|
|
44
44
|
or ambiguous source files and reports older than their modified source fail; zero modified
|
|
45
45
|
executable lines is explicit N/A. Always regenerate JaCoCo XML after the final source change.
|
|
46
|
-
Record CI as pending until the remote pipeline actually passes; local green is not remote green.
|
|
47
46
|
Never substitute `HEAD`, a mutable ref, project defaults, or current session settings for the
|
|
48
|
-
task-frozen baseline SHA and threshold.
|
|
49
|
-
|
|
47
|
+
task-frozen baseline SHA and threshold. `ec-tdd-init` still generates a GitLab job that can run
|
|
48
|
+
the same tool, but remote pipeline execution and status are outside Harness acceptance. Never
|
|
49
|
+
request an intermediate commit or push merely to obtain CI evidence.
|
|
50
50
|
|
|
51
51
|
The main Agent may run commands inline. Dispatch verifier sub-agents only when checks are
|
|
52
52
|
independent and parallel execution materially saves time or isolates specialist environments.
|
|
@@ -86,23 +86,11 @@ For TDD coverage, copy the tool output into `coverage`: `baseline_sha`, `covered
|
|
|
86
86
|
`applicable:false` plus the tool's reason only for zero executable modified lines. A percentage
|
|
87
87
|
below the frozen threshold fails even when ordinary tests pass.
|
|
88
88
|
|
|
89
|
-
Append
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
{
|
|
95
|
-
"ci": {
|
|
96
|
-
"provider": "gitlab",
|
|
97
|
-
"pipeline_url": "https://gitlab.example/.../pipelines/123",
|
|
98
|
-
"job_name": "changed-line-coverage",
|
|
99
|
-
"status": "success"
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
Both records must preserve the same task-frozen baseline and threshold. A local-only result,
|
|
105
|
-
pending/failed pipeline, missing job identity, or synthetic remote pass cannot satisfy MEMORY.
|
|
89
|
+
Append one coverage record with `coverage_scope:"local"` per repository (and per Canonical
|
|
90
|
+
source task). The state gate also requires a passed local `check_type:"test"` record for the same
|
|
91
|
+
owner. The coverage record preserves the task-frozen baseline and threshold. Do not append or
|
|
92
|
+
wait for GitLab pipeline evidence; historical remote coverage records are ignored by acceptance
|
|
93
|
+
without modifying or deleting the stored records.
|
|
106
94
|
|
|
107
95
|
For `type=tdd-init`, the infrastructure receipt must already have been recorded during IMPLEMENT
|
|
108
96
|
and reviewed with the rest of the implementation. Run only `easy_coding_tdd_readiness.py check`
|
|
@@ -53,8 +53,9 @@ First run `ec-init`; daily work goes through `ec-workflow`.
|
|
|
53
53
|
there is no enable-now/init-later state. The dedicated `tdd-init` task always freezes TDD off and
|
|
54
54
|
initializes only changed-line coverage infrastructure, never historical business-test coverage.
|
|
55
55
|
Disabled TDD adds no CI scan, JaCoCo work, commands, artifacts, or stronger gates. Enabled TDD
|
|
56
|
-
applies only to Java code tasks and requires lifecycle, review, local
|
|
57
|
-
|
|
56
|
+
applies only to Java code tasks and requires lifecycle, review, passed local unit tests, and
|
|
57
|
+
local coverage for production lines changed since the task baseline. `ec-tdd-init` still
|
|
58
|
+
generates GitLab TEST-stage automation, but remote CI status is not Harness acceptance evidence.
|
|
58
59
|
- Confirmation-required edges use `pending_transition`; automatic edges use the restricted
|
|
59
60
|
`auto-transition` API. A read-only task creates no test-strategy.md, never enters REVIEW,
|
|
60
61
|
VERIFICATION, or MEMORY, and writes no task memory.
|
|
@@ -51,8 +51,9 @@ First run `/ec-init`; daily work goes through `/ec-workflow`.
|
|
|
51
51
|
there is no enable-now/init-later state. The dedicated `tdd-init` task always freezes TDD off and
|
|
52
52
|
initializes only changed-line coverage infrastructure, never historical business-test coverage.
|
|
53
53
|
Disabled TDD adds no CI scan, JaCoCo work, commands, artifacts, or stronger gates. Enabled TDD
|
|
54
|
-
applies only to Java code tasks and requires lifecycle, review, local
|
|
55
|
-
|
|
54
|
+
applies only to Java code tasks and requires lifecycle, review, passed local unit tests, and
|
|
55
|
+
local coverage for production lines changed since the task baseline. `ec-tdd-init` still
|
|
56
|
+
generates GitLab TEST-stage automation, but remote CI status is not Harness acceptance evidence.
|
|
56
57
|
- Confirmation-required edges use `pending_transition`; automatic edges use the restricted
|
|
57
58
|
`auto-transition` API. A read-only task creates no test-strategy.md, never enters REVIEW,
|
|
58
59
|
VERIFICATION, or MEMORY, and writes no task memory.
|
|
@@ -2526,6 +2526,13 @@ def validate_verification_readiness(root: Path, task_id: str, task: dict) -> Non
|
|
|
2526
2526
|
and record.get("config_fingerprint") == fingerprints["config_fingerprint"]
|
|
2527
2527
|
and is_non_empty_string(record.get("check"))
|
|
2528
2528
|
):
|
|
2529
|
+
if (
|
|
2530
|
+
task.get("tdd_enabled") is True
|
|
2531
|
+
and record.get("check_type") == "coverage"
|
|
2532
|
+
and record.get("coverage_scope") == "gitlab"
|
|
2533
|
+
):
|
|
2534
|
+
# 远程 CI 只作为生成的自动化能力,历史 pending/failed 记录不再参与本地验收。
|
|
2535
|
+
continue
|
|
2529
2536
|
check = str(record["check"])
|
|
2530
2537
|
if task.get("tdd_enabled") is True and record.get("check_type") == "coverage":
|
|
2531
2538
|
check = f"{check}\0{record.get('coverage_scope') or ''}"
|
|
@@ -2608,6 +2615,12 @@ def validate_verification_readiness(root: Path, task_id: str, task: dict) -> Non
|
|
|
2608
2615
|
)
|
|
2609
2616
|
if task.get("tdd_enabled") is True:
|
|
2610
2617
|
require_tdd_readiness(root)
|
|
2618
|
+
test_records = [
|
|
2619
|
+
record
|
|
2620
|
+
for record in latest_by_check.values()
|
|
2621
|
+
if record.get("check_type") == "test"
|
|
2622
|
+
and record.get("applicable") is not False
|
|
2623
|
+
]
|
|
2611
2624
|
coverage_records = [
|
|
2612
2625
|
record
|
|
2613
2626
|
for record in latest_by_check.values()
|
|
@@ -2618,6 +2631,17 @@ def validate_verification_readiness(root: Path, task_id: str, task: dict) -> Non
|
|
|
2618
2631
|
"TDD verification requires changed-production-line JaCoCo coverage evidence."
|
|
2619
2632
|
)
|
|
2620
2633
|
if is_spec_task:
|
|
2634
|
+
tested_source_tasks = {
|
|
2635
|
+
str(record.get("source_task_id") or "") for record in test_records
|
|
2636
|
+
}
|
|
2637
|
+
missing_test_tasks = sorted(
|
|
2638
|
+
set(task_repositories) - tested_source_tasks
|
|
2639
|
+
)
|
|
2640
|
+
if missing_test_tasks:
|
|
2641
|
+
raise StateError(
|
|
2642
|
+
"TDD Canonical verification requires local unit-test evidence for every selected source task: "
|
|
2643
|
+
+ ", ".join(missing_test_tasks)
|
|
2644
|
+
)
|
|
2621
2645
|
covered_source_tasks = {
|
|
2622
2646
|
str(record.get("source_task_id") or "") for record in coverage_records
|
|
2623
2647
|
}
|
|
@@ -2629,19 +2653,16 @@ def validate_verification_readiness(root: Path, task_id: str, task: dict) -> Non
|
|
|
2629
2653
|
"TDD Canonical verification requires separate coverage evidence for every selected source task: "
|
|
2630
2654
|
+ ", ".join(missing_coverage_tasks)
|
|
2631
2655
|
)
|
|
2632
|
-
|
|
2656
|
+
elif not test_records:
|
|
2657
|
+
raise StateError(
|
|
2658
|
+
"TDD verification requires passed local unit-test evidence."
|
|
2659
|
+
)
|
|
2633
2660
|
for record in coverage_records:
|
|
2634
2661
|
scope = str(record.get("coverage_scope") or "")
|
|
2635
|
-
if scope
|
|
2662
|
+
if scope != "local":
|
|
2636
2663
|
raise StateError(
|
|
2637
|
-
"TDD coverage evidence must identify coverage_scope as local
|
|
2664
|
+
"TDD coverage evidence must identify coverage_scope as local."
|
|
2638
2665
|
)
|
|
2639
|
-
owner = (
|
|
2640
|
-
str(record.get("source_task_id") or "")
|
|
2641
|
-
if is_spec_task
|
|
2642
|
-
else "project"
|
|
2643
|
-
)
|
|
2644
|
-
coverage_scopes_by_owner.setdefault(owner, set()).add(scope)
|
|
2645
2666
|
expected_threshold = task.get("tdd_coverage_threshold")
|
|
2646
2667
|
expected_baselines = task.get("tdd_baselines")
|
|
2647
2668
|
if (
|
|
@@ -2656,18 +2677,6 @@ def validate_verification_readiness(root: Path, task_id: str, task: dict) -> Non
|
|
|
2656
2677
|
coverage = record.get("coverage")
|
|
2657
2678
|
if not isinstance(coverage, dict):
|
|
2658
2679
|
raise StateError("TDD coverage evidence must include the coverage result object.")
|
|
2659
|
-
if record.get("coverage_scope") == "gitlab":
|
|
2660
|
-
ci = record.get("ci")
|
|
2661
|
-
if (
|
|
2662
|
-
not isinstance(ci, dict)
|
|
2663
|
-
or ci.get("provider") != "gitlab"
|
|
2664
|
-
or ci.get("status") != "success"
|
|
2665
|
-
or not is_non_empty_string(ci.get("pipeline_url"))
|
|
2666
|
-
or not is_non_empty_string(ci.get("job_name"))
|
|
2667
|
-
):
|
|
2668
|
-
raise StateError(
|
|
2669
|
-
"GitLab coverage evidence requires a successful pipeline URL and job name."
|
|
2670
|
-
)
|
|
2671
2680
|
total = coverage.get("total_lines")
|
|
2672
2681
|
covered = coverage.get("covered_lines")
|
|
2673
2682
|
percentage = coverage.get("percentage")
|
|
@@ -2722,18 +2731,6 @@ def validate_verification_readiness(root: Path, task_id: str, task: dict) -> Non
|
|
|
2722
2731
|
raise StateError(
|
|
2723
2732
|
f"TDD changed-line coverage must meet the frozen {threshold}% threshold."
|
|
2724
2733
|
)
|
|
2725
|
-
expected_coverage_owners = set(task_repositories) if is_spec_task else {"project"}
|
|
2726
|
-
missing_scopes = [
|
|
2727
|
-
f"{owner}:{scope}"
|
|
2728
|
-
for owner in sorted(expected_coverage_owners)
|
|
2729
|
-
for scope in ("local", "gitlab")
|
|
2730
|
-
if scope not in coverage_scopes_by_owner.get(owner, set())
|
|
2731
|
-
]
|
|
2732
|
-
if missing_scopes:
|
|
2733
|
-
raise StateError(
|
|
2734
|
-
"TDD verification requires both local and successful GitLab coverage gates: "
|
|
2735
|
-
+ ", ".join(missing_scopes)
|
|
2736
|
-
)
|
|
2737
2734
|
if task.get("workflow_mode") == "strict":
|
|
2738
2735
|
if is_spec_task:
|
|
2739
2736
|
check_types_by_repository: dict[str, set[str]] = {
|
|
@@ -3098,7 +3095,13 @@ def validate_analysis_readiness(
|
|
|
3098
3095
|
strategy_content = test_strategy.read_text(encoding="utf-8")
|
|
3099
3096
|
except OSError:
|
|
3100
3097
|
strategy_content = ""
|
|
3101
|
-
required_tdd_markers = [
|
|
3098
|
+
required_tdd_markers = [
|
|
3099
|
+
"TDD",
|
|
3100
|
+
"JaCoCo",
|
|
3101
|
+
"baseline",
|
|
3102
|
+
"local_test_gate: required",
|
|
3103
|
+
"remote_ci_acceptance: non-blocking",
|
|
3104
|
+
]
|
|
3102
3105
|
missing_tdd_markers = [
|
|
3103
3106
|
marker for marker in required_tdd_markers if marker.lower() not in strategy_content.lower()
|
|
3104
3107
|
]
|