@blxzer/cursor-trellis 0.3.5 → 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.
- package/CHANGELOG.md +69 -0
- package/README.md +13 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +3 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/goal/index.d.ts +3 -0
- package/dist/commands/goal/index.d.ts.map +1 -0
- package/dist/commands/goal/index.js +159 -0
- package/dist/commands/goal/index.js.map +1 -0
- package/dist/commands/goal/review.d.ts +6 -0
- package/dist/commands/goal/review.d.ts.map +1 -0
- package/dist/commands/goal/review.js +28 -0
- package/dist/commands/goal/review.js.map +1 -0
- package/dist/commands/sdk/run.d.ts.map +1 -1
- package/dist/commands/sdk/run.js +2 -27
- package/dist/commands/sdk/run.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +5 -1
- package/dist/commands/update.js.map +1 -1
- package/dist/configurators/workflow.d.ts.map +1 -1
- package/dist/configurators/workflow.js +51 -2
- package/dist/configurators/workflow.js.map +1 -1
- package/dist/constants/paths.d.ts +4 -0
- package/dist/constants/paths.d.ts.map +1 -1
- package/dist/constants/paths.js +4 -0
- package/dist/constants/paths.js.map +1 -1
- package/dist/goal/action-packet.d.ts +89 -0
- package/dist/goal/action-packet.d.ts.map +1 -0
- package/dist/goal/action-packet.js +113 -0
- package/dist/goal/action-packet.js.map +1 -0
- package/dist/goal/audit.d.ts +14 -0
- package/dist/goal/audit.d.ts.map +1 -0
- package/dist/goal/audit.js +12 -0
- package/dist/goal/audit.js.map +1 -0
- package/dist/goal/constants.d.ts +26 -0
- package/dist/goal/constants.d.ts.map +1 -0
- package/dist/goal/constants.js +24 -0
- package/dist/goal/constants.js.map +1 -0
- package/dist/goal/paths.d.ts +8 -0
- package/dist/goal/paths.d.ts.map +1 -0
- package/dist/goal/paths.js +36 -0
- package/dist/goal/paths.js.map +1 -0
- package/dist/goal/preflight.d.ts +21 -0
- package/dist/goal/preflight.d.ts.map +1 -0
- package/dist/goal/preflight.js +97 -0
- package/dist/goal/preflight.js.map +1 -0
- package/dist/goal/review-seam.d.ts +44 -0
- package/dist/goal/review-seam.d.ts.map +1 -0
- package/dist/goal/review-seam.js +153 -0
- package/dist/goal/review-seam.js.map +1 -0
- package/dist/goal/reviewer-rules.d.ts +13 -0
- package/dist/goal/reviewer-rules.d.ts.map +1 -0
- package/dist/goal/reviewer-rules.js +153 -0
- package/dist/goal/reviewer-rules.js.map +1 -0
- package/dist/goal/reviewer.d.ts +9 -0
- package/dist/goal/reviewer.d.ts.map +1 -0
- package/dist/goal/reviewer.js +54 -0
- package/dist/goal/reviewer.js.map +1 -0
- package/dist/goal/runtime.d.ts +32 -0
- package/dist/goal/runtime.d.ts.map +1 -0
- package/dist/goal/runtime.js +242 -0
- package/dist/goal/runtime.js.map +1 -0
- package/dist/goal/sdk-client.d.ts +10 -0
- package/dist/goal/sdk-client.d.ts.map +1 -0
- package/dist/goal/sdk-client.js +34 -0
- package/dist/goal/sdk-client.js.map +1 -0
- package/dist/goal/state.d.ts +40 -0
- package/dist/goal/state.d.ts.map +1 -0
- package/dist/goal/state.js +37 -0
- package/dist/goal/state.js.map +1 -0
- package/dist/goal/task-triggers.d.ts +15 -0
- package/dist/goal/task-triggers.d.ts.map +1 -0
- package/dist/goal/task-triggers.js +23 -0
- package/dist/goal/task-triggers.js.map +1 -0
- package/dist/goal/walls.d.ts +12 -0
- package/dist/goal/walls.d.ts.map +1 -0
- package/dist/goal/walls.js +65 -0
- package/dist/goal/walls.js.map +1 -0
- package/dist/goal/worker-prompt.d.ts +13 -0
- package/dist/goal/worker-prompt.d.ts.map +1 -0
- package/dist/goal/worker-prompt.js +41 -0
- package/dist/goal/worker-prompt.js.map +1 -0
- package/dist/goal/worker.d.ts +42 -0
- package/dist/goal/worker.d.ts.map +1 -0
- package/dist/goal/worker.js +180 -0
- package/dist/goal/worker.js.map +1 -0
- package/dist/migrations/manifests/0.3.5.json +9 -0
- package/dist/migrations/manifests/0.3.6.json +9 -0
- package/dist/migrations/manifests/0.4.0.json +9 -0
- package/dist/templates/common/commands/continue.md +15 -3
- package/dist/templates/common/skills/check.md +7 -4
- package/dist/templates/cursor/agents/cstl-check.md +1 -0
- package/dist/templates/cursor/fixtures/expected-rules.d.ts.map +1 -1
- package/dist/templates/cursor/fixtures/expected-rules.js +6 -1
- package/dist/templates/cursor/fixtures/expected-rules.js.map +1 -1
- package/dist/templates/cursor/rules/cstl-cursor-modes.mdc +32 -0
- package/dist/templates/cursor/rules/cstl-triage.mdc +2 -4
- package/dist/templates/cursor/rules/retrieval-routing.mdc +26 -7
- package/dist/templates/markdown/index.d.ts +9 -0
- package/dist/templates/markdown/index.d.ts.map +1 -1
- package/dist/templates/markdown/index.js +9 -0
- package/dist/templates/markdown/index.js.map +1 -1
- package/dist/templates/markdown/spec/guides/artifact-locale-guide.md.txt +93 -0
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +7 -7
- package/dist/templates/markdown/spec/guides/cursor-context-injection-guide.md.txt +38 -21
- package/dist/templates/markdown/spec/guides/cursor-native-modes-guide.md.txt +125 -0
- package/dist/templates/markdown/spec/guides/cursor-subagent-policy.md.txt +10 -8
- package/dist/templates/markdown/spec/guides/debug-loop-guide.md.txt +227 -0
- package/dist/templates/markdown/spec/guides/goal-release-regression-runbook.md.txt +132 -0
- package/dist/templates/markdown/spec/guides/index.md.txt +144 -104
- package/dist/templates/markdown/spec/guides/injection-budget-guide.md.txt +111 -0
- package/dist/templates/markdown/spec/guides/prototype-guide.md.txt +139 -0
- package/dist/templates/markdown/spec/guides/retrieval-daily-guide.md.txt +28 -6
- package/dist/templates/markdown/spec/guides/test-discipline-guide.md.txt +138 -0
- package/dist/templates/markdown/spec/guides/verification-strength-guide.md.txt +185 -0
- package/dist/templates/shared-hooks/session-start.py +10 -0
- package/dist/templates/trellis/config.yaml +18 -0
- package/dist/templates/trellis/index.d.ts +17 -0
- package/dist/templates/trellis/index.d.ts.map +1 -1
- package/dist/templates/trellis/index.js +40 -0
- package/dist/templates/trellis/index.js.map +1 -1
- package/dist/templates/trellis/pool/README.md +103 -0
- package/dist/templates/trellis/pool/items/.gitkeep +0 -0
- package/dist/templates/trellis/pool/plan.md +26 -0
- package/dist/templates/trellis/scripts/common/artifact_locale.py +278 -0
- package/dist/templates/trellis/scripts/common/codebase_retrieval_router.py +37 -2
- package/dist/templates/trellis/scripts/common/config.py +39 -0
- package/dist/templates/trellis/scripts/common/injection_budget.py +317 -0
- package/dist/templates/trellis/scripts/common/parent_orchestration.py +161 -5
- package/dist/templates/trellis/scripts/common/pool_store.py +702 -0
- package/dist/templates/trellis/scripts/common/retrieval_agent_instructions.py +9 -3
- package/dist/templates/trellis/scripts/common/session_context.py +32 -4
- package/dist/templates/trellis/scripts/common/session_memory.py +26 -0
- package/dist/templates/trellis/scripts/common/subagent_dispatch.py +74 -9
- package/dist/templates/trellis/scripts/common/task_context.py +18 -0
- package/dist/templates/trellis/scripts/common/task_dashboard.py +24 -1
- package/dist/templates/trellis/scripts/common/task_dependencies.py +673 -0
- package/dist/templates/trellis/scripts/common/task_gates.py +58 -5
- package/dist/templates/trellis/scripts/common/task_map.py +40 -8
- package/dist/templates/trellis/scripts/common/task_store.py +400 -39
- package/dist/templates/trellis/scripts/common/test_depends_mode_block.py +489 -0
- package/dist/templates/trellis/scripts/common/test_observable_defaults.py +135 -0
- package/dist/templates/trellis/scripts/common/test_pool_store.py +428 -0
- package/dist/templates/trellis/scripts/common/test_task_dependencies.py +345 -0
- package/dist/templates/trellis/scripts/cursor_retrieval_probe_prompt.md +14 -12
- package/dist/templates/trellis/scripts/generate_dispatch_prompt.py +182 -0
- package/dist/templates/trellis/scripts/injection_budget_probe.py +69 -0
- package/dist/templates/trellis/scripts/pool.py +192 -0
- package/dist/templates/trellis/scripts/retrieval_probe_matrix_template.json +3 -3
- package/dist/templates/trellis/scripts/spec_health_outcomes.py +160 -0
- package/dist/templates/trellis/scripts/task.py +85 -1
- package/dist/templates/trellis/scripts/verify_evidence_probe.py +138 -0
- package/dist/templates/trellis/tasks/locale/en/default-prd.md +19 -0
- package/dist/templates/trellis/tasks/locale/zh/default-prd.md +19 -0
- package/dist/templates/trellis/workflow.md +55 -5
- package/package.json +2 -2
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Injection Budget Guide
|
|
2
|
+
|
|
3
|
+
> **Purpose**: Allocate context injection across **reliable Cursor channels** with measurable caps —「完整 = 证据密度」, not unbounded prose.
|
|
4
|
+
|
|
5
|
+
**Matrix input:** `08-06-cstl-p0-channel-baseline-matrix` → `research/channel-matrix.md` (C01–C04, C16).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Non-goals
|
|
10
|
+
|
|
11
|
+
- **No `beforeSubmitPrompt` injection** — C04 stays telemetry-only until Cursor changelog proves otherwise.
|
|
12
|
+
- **No black-box silent injection** — Layer 2 and jsonl loads emit stderr manifest lines.
|
|
13
|
+
- **No weakening gates** — Triage (`cstl-triage.mdc`), execution approval, and retrieval policy remain always-on.
|
|
14
|
+
- **No Auto-Trigger Skill as retrieval primary** — C16 stays Rules + `route_codebase_retrieval.py --instructions`.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 2. Channel budget tiers
|
|
19
|
+
|
|
20
|
+
| Tier | Channels | When | Budget |
|
|
21
|
+
| --- | --- | --- | --- |
|
|
22
|
+
| **Per-turn hard** | C01 Rules, C02 AGENTS | Every agent turn | Rules total warn 20 KiB / fail 32 KiB; AGENTS CSTL block warn 4 KiB |
|
|
23
|
+
| **Session once** | C03 sessionStart | New session | Keep dashboard/workflow summary compact; not a substitute for per-turn rules |
|
|
24
|
+
| **Zero** | C04 beforeSubmit | Every message | **0** — log only |
|
|
25
|
+
| **Subagent only** | C06 Layer 2 | `generate_dispatch_prompt` → Task | Role default `max_chars` + jsonl caps (§3) |
|
|
26
|
+
| **On demand** | C16 retrieval | When agent needs a plan | Rules default order or router CLI; no per-message plan block |
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 3. JSONL manifest budgets (implement / check)
|
|
31
|
+
|
|
32
|
+
Curate **spec/research only** — never pre-register code paths you will edit.
|
|
33
|
+
|
|
34
|
+
| Limit | Value | Enforcement |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| Max entries | 8 | Skip excess at Layer 2 load; `task.py validate` WARN |
|
|
37
|
+
| Max single expansion | 12,000 chars | Skip file/directory block |
|
|
38
|
+
| Max total jsonl body | 48,000 chars | Skip when cumulative would exceed |
|
|
39
|
+
|
|
40
|
+
**Curator rules:**
|
|
41
|
+
|
|
42
|
+
1. Prefer **index + one layer spec** over whole package trees.
|
|
43
|
+
2. Use `task.py add-context` with a one-line **reason** (replayable intent).
|
|
44
|
+
3. Delete the seed `_example` row when adding real entries.
|
|
45
|
+
4. Full task artifacts (`prd.md`, `design.md`, `implement.md`) are **always** embedded separately — do not duplicate them in jsonl.
|
|
46
|
+
|
|
47
|
+
**Dispatch manifest (stderr):**
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
[subagent-dispatch] injection-budget: .cstl/tasks/.../implement.jsonl loaded 2 entries (8421 chars): ...
|
|
51
|
+
[subagent-dispatch] injection-budget: skipped path: total cap (...)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 4. Layer 2 role defaults
|
|
57
|
+
|
|
58
|
+
When `--max-chars` is omitted, `generate_dispatch_prompt.py` uses:
|
|
59
|
+
|
|
60
|
+
| Role | Default `max_chars` |
|
|
61
|
+
| --- | --- |
|
|
62
|
+
| implement | 96,000 |
|
|
63
|
+
| check | 64,000 |
|
|
64
|
+
| research | 48,000 |
|
|
65
|
+
|
|
66
|
+
Override per dispatch when a task truly needs more — document the override in `implement.md` DSC and `verify.md`.
|
|
67
|
+
|
|
68
|
+
Truncation order after jsonl budget: whole context string tail-truncated with `...[truncated]...` warning.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 5. alwaysApply rule hygiene
|
|
73
|
+
|
|
74
|
+
Before adding a new `.cursor/rules/*.mdc` with `alwaysApply: true`:
|
|
75
|
+
|
|
76
|
+
1. Confirm the content **must** be visible **every turn** (see `cursor-context-injection-guide.md`).
|
|
77
|
+
2. Run `python ./.cstl/scripts/injection_budget_probe.py --repo-root .`.
|
|
78
|
+
3. If total alwaysApply exceeds **20 KiB**, trim or move detail to on-demand spec / `get_context.py`.
|
|
79
|
+
|
|
80
|
+
**Rollback:** remove or scope the new rule; re-run probe.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 6. Observability probe
|
|
85
|
+
|
|
86
|
+
```powershell
|
|
87
|
+
# Workspace surfaces
|
|
88
|
+
python ./.cstl/scripts/injection_budget_probe.py --repo-root .
|
|
89
|
+
|
|
90
|
+
# Task jsonl + dispatch size
|
|
91
|
+
python ./.cstl/scripts/injection_budget_probe.py --repo-root . --task .cstl/tasks/<task-dir> --dispatch-role implement
|
|
92
|
+
|
|
93
|
+
# CI / gate style (fail on WARN or rules >32KiB)
|
|
94
|
+
python ./.cstl/scripts/injection_budget_probe.py --repo-root . --strict
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Constants live in `.cstl/scripts/common/injection_budget.py` (single source).
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 7. Related
|
|
102
|
+
|
|
103
|
+
- [Cursor context injection guide](./cursor-context-injection-guide.md) — channel reliability matrix
|
|
104
|
+
- [Cursor subagent policy](./cursor-subagent-policy.md) — Layer 2 dispatch contract
|
|
105
|
+
- [Verification strength guide](./verification-strength-guide.md) — evidence density for closeout (orthogonal axis)
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 8. Rollback
|
|
110
|
+
|
|
111
|
+
Revert `injection_budget.py`, probe script, `subagent_dispatch` budget branch, validate WARNs, and this guide. Layer 2 returns to unbounded jsonl expansion; C04 remains telemetry-only.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Prototype Guide(原型纪律)
|
|
2
|
+
|
|
3
|
+
> **Purpose**: 用一次性代码回答**设计问题**——先写清问题,再由问题决定原型形态;答案折叠进真实代码(**重写不 mv**),原型留证后清理,不留工作区腐烂。本 harness:**LOGIC / Python 默认,UI 不适用(N/A)**。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Purpose / When to use
|
|
8
|
+
|
|
9
|
+
**原型是一次性代码,回答一个设计问题。** 什么时候用:
|
|
10
|
+
|
|
11
|
+
- 要验证某个**机制 / 状态模型 / 算法**「感不感觉对」——在纸上难推演的 case,跑起来看证据。
|
|
12
|
+
- 要在 design / prd 落结论前,先对「如果……会怎样」拿到可观察的事实。
|
|
13
|
+
- 结论已知会写回真实代码,但想让实现者先摸一遍形状。
|
|
14
|
+
|
|
15
|
+
原型唯一的产出是**答案**,不是代码。
|
|
16
|
+
|
|
17
|
+
## 2. Non-goals
|
|
18
|
+
|
|
19
|
+
- **不接真实 DB / 服务**:原型依赖一律假数据 / 内存 / 显式标记的临时本地文件。
|
|
20
|
+
- **不直接升生产**:原型的代码路径不是生产代码的捷径;折叠时**重写**,不 `mv`。
|
|
21
|
+
- **不做 UI(本 harness)**:本 harness 无 UI 面,UI 原型不适用(见 §6)。
|
|
22
|
+
- **不替代测试 / 调试 / 需求发现**:见 §12 边界(单向链)。
|
|
23
|
+
|
|
24
|
+
## 3. Hard rules
|
|
25
|
+
|
|
26
|
+
1. **问题决定形态** — 先写设计问题,再选原型形态;问题写不清,先不写代码。
|
|
27
|
+
2. **丢弃式(throwaway)** — 从第一天起就是一次性:不接真实 DB/服务;**不加测试、不泛化**(可跑即可);默认**无持久化**(或仅临时本地文件且须清理)。
|
|
28
|
+
3. **状态可见** — 每次 action 后打印/记录关键状态(print / 日志 / 简单 TUI),答案从可见状态里读出来。
|
|
29
|
+
4. **答案折叠** — 结论写回 design / prd / 真实代码;原型代码本身**不提升**为生产代码,折叠时在真实 module 里**重写**,不 `mv`。
|
|
30
|
+
5. **留证后可清理** — 答案折叠 + 留证完成后,删除工作区里的原型(§9 / §10),不留腐烂。
|
|
31
|
+
|
|
32
|
+
## 4. Step 0 — Write the design question
|
|
33
|
+
|
|
34
|
+
开始前写一句话,并放进原型文件头:
|
|
35
|
+
|
|
36
|
+
> 这个原型要回答:____________
|
|
37
|
+
|
|
38
|
+
回答不了这个问题,就说明原型还没开始对。
|
|
39
|
+
|
|
40
|
+
## 5. Shape: LOGIC(Python)— default for this harness
|
|
41
|
+
|
|
42
|
+
本 harness 的 LOGIC 默认形态(替代 Matt 单 HTML 默认;本仓库无 UI 面):
|
|
43
|
+
|
|
44
|
+
- **单个可运行脚本**,路径二选一:
|
|
45
|
+
- `.tmp/prototypes/<slug>/run.py`(工作区 scratch;**惰性创建,不预建空目录**)
|
|
46
|
+
- 任务 `research/prototype-<slug>.py`(工作位置即留证位置,见 §9)
|
|
47
|
+
- **逻辑与 demo 入口分离**:文件内分两段——
|
|
48
|
+
- `# --- logic (portable) ---`:纯逻辑函数(无副作用、依赖从参数注入),折叠时可提起进真实代码
|
|
49
|
+
- `# --- demo entry ---`:构造输入、调用、打印状态,只服务于「跑起来看答案」
|
|
50
|
+
- **运行**:`python run.py` 即得可观察输出,无额外步骤。
|
|
51
|
+
- 最小骨架示例见 §13。
|
|
52
|
+
|
|
53
|
+
## 6. Shape: UI — N/A for this harness
|
|
54
|
+
|
|
55
|
+
**不适用 / N/A。** 本 harness 没有 UI 面(agent CLI + 文档工作流),**不写 UI 脚手架**、不做 UI 变体原型、不引入 UI 分支。若上游项目需要 UI 原型,那是上游项目自己的事,不进本 harness 主树。
|
|
56
|
+
|
|
57
|
+
## 7. Visibility of state
|
|
58
|
+
|
|
59
|
+
原型回答问题的机制必须**可观察**:
|
|
60
|
+
|
|
61
|
+
- 每次 action 后打印完整相关状态,不省略中间态。
|
|
62
|
+
- 关键分支打印路径标签;比较类问题打印两侧差异。
|
|
63
|
+
- 输出讲不清 → 答案就落不进 design。
|
|
64
|
+
|
|
65
|
+
## 8. Capture the answer → fold into real code
|
|
66
|
+
|
|
67
|
+
原型结束后两件事:
|
|
68
|
+
|
|
69
|
+
1. **折叠答案**:把结论(问题 + 判定 + 理由)写回 design / prd / 真实代码;代码折叠时在真实 module 里**重写** logic 段(贴合真实接口与错误处理),**不 `mv` 原型文件升生产**。
|
|
70
|
+
2. **留证原型**(primary source,可回看「当时怎么答的」)——见 §9。
|
|
71
|
+
|
|
72
|
+
## 9. Evidence(留证:throwaway 分支 / 路径快照)
|
|
73
|
+
|
|
74
|
+
两层留证机制,**清理前必须确认留证已落**:
|
|
75
|
+
|
|
76
|
+
| 层 | 手段 | 适用 |
|
|
77
|
+
| --- | --- | --- |
|
|
78
|
+
| A | git **throwaway 分支**提交(如 `proto/<slug>`,离开 main),留上下文指针 | git 仓库(如 cursor-trellis / smart-search) |
|
|
79
|
+
| B | **路径快照**:复制到 `.cstl/tasks/<task>/research/prototype-<slug>.py`(或任务目录等价位置),并在 handoff.md / verify.md 记录路径 | **非 git 仓库——本 harness 根目录的默认手段** |
|
|
80
|
+
|
|
81
|
+
- 工作位置本身是任务 `research/prototype-<slug>.py` 时,即工作即留证,无需再复制。
|
|
82
|
+
- A / B 可并用。
|
|
83
|
+
|
|
84
|
+
## 10. Cleanup / archive(清理:不留腐烂)
|
|
85
|
+
|
|
86
|
+
- **何时**:答案已折叠 + 留证已落,原型不再需要。
|
|
87
|
+
- **做什么**:删除 `.tmp/prototypes/<slug>/`——scratch 工作区不留腐烂;若原型躺在任务 `research/` 下,那本身就是留证,保留并按任务归档机制处理。
|
|
88
|
+
- **不做**:把原型当长期分支 / 常驻目录养;在 main 上留下 throwaway 痕迹。
|
|
89
|
+
|
|
90
|
+
## 11. Anti-patterns(反模式清单)
|
|
91
|
+
|
|
92
|
+
| 反模式 | 信号 | 修正 |
|
|
93
|
+
| --- | --- | --- |
|
|
94
|
+
| 过早泛化 | 加参数 / 抽象 / 配置,问题还没回答完 | 回到最小:只够回答问题 |
|
|
95
|
+
| 接生产依赖 | 连真实 DB / 服务 / 凭据 | 假数据 / 内存 / 显式临时文件 |
|
|
96
|
+
| 当长期分支养 | 原型分支 / 目录持续叠加功能、迟迟不折叠 | 答案到手即折叠 + 清理 |
|
|
97
|
+
| 在本项目启用 UI 分支 | 写 UI 脚手架 / UI 变体原型 | 本 harness UI N/A,直接不做 |
|
|
98
|
+
| `mv` 升生产 | 原型文件直接改名 / 移入真实路径 | 折叠时重写进真实 module |
|
|
99
|
+
| 答案不留证 | 跑完即删、结论没落任何地方 | §8 折叠 + §9 留证先行 |
|
|
100
|
+
|
|
101
|
+
## 12. Relation to debug-loop / test-discipline / brainstorm(边界,单向链)
|
|
102
|
+
|
|
103
|
+
- **Debug Loop Guide**:debug-loop 用 throwaway harness 回答「**为什么坏了**」(bug / 性能回归,诊断进行中);原型回答「**这个设计 / 机制对不对**」(尚无 bug,设计前)。原型**不替代**调试纪律。
|
|
104
|
+
- **Test Discipline Guide**:test-discipline 管生产测试写作(pre-agreed seams、反模式、mock 边界);原型**不加测试**(可跑即可)。原型**不替代**测试纪律。
|
|
105
|
+
- **brainstorm**:brainstorm 管需求发现(用户想要什么);原型管设计验证(机制怎么实现才对)。原型**不替代** brainstorm。
|
|
106
|
+
- 衔接点:原型的可运行骨架可能成为 debug-loop 反馈环的起点或真实测试的输入样例——那是**下游复用**,不是原型的职责。
|
|
107
|
+
|
|
108
|
+
## 13. Minimal skeleton(LOGIC, Python)
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
# prototype: <slug> — throwaway,回答:「________________」 (§4 设计问题)
|
|
112
|
+
# 运行: python run.py;不接真实依赖;答案折叠后清理或留证(§9/§10)
|
|
113
|
+
|
|
114
|
+
# --- logic (portable) ---
|
|
115
|
+
def next_state(current: str, event: str) -> str:
|
|
116
|
+
transitions = {
|
|
117
|
+
("idle", "start"): "running",
|
|
118
|
+
("running", "stop"): "stopped",
|
|
119
|
+
}
|
|
120
|
+
return transitions.get((current, event), current)
|
|
121
|
+
|
|
122
|
+
# --- demo entry ---
|
|
123
|
+
if __name__ == "__main__":
|
|
124
|
+
state = "idle"
|
|
125
|
+
for event in ["start", "pause", "stop"]:
|
|
126
|
+
state = next_state(state, event)
|
|
127
|
+
print(f"{event:>8} -> {state}") # 状态可见:每次 action 后打印
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## 14. Checklist
|
|
131
|
+
|
|
132
|
+
- [ ] §4 设计问题已写清(一句话,在文件头)
|
|
133
|
+
- [ ] 形态:LOGIC / Python 单脚本;UI 不适用(未写 UI 脚手架)
|
|
134
|
+
- [ ] 不接真实 DB / 服务;无持久化(或显式临时文件且会清理)
|
|
135
|
+
- [ ] 无测试、无泛化——可跑即可
|
|
136
|
+
- [ ] 状态可见:关键状态每次 action 后打印
|
|
137
|
+
- [ ] 答案已折叠(写回 design / prd / 真实代码;**重写不 mv**)
|
|
138
|
+
- [ ] 留证已落(git throwaway 分支,或非 git 路径快照到任务 `research/`)
|
|
139
|
+
- [ ] 清理完成:`.tmp/prototypes/<slug>/` 已删,无工作区腐烂
|
|
@@ -20,18 +20,40 @@ Ask: *If this answer were wrong because the world or a third-party API moved, wo
|
|
|
20
20
|
**NO examples:** symbol location / call chains; in-repo Trellis contracts; behavior of the code you are editing; pure rename/lint inside known files.
|
|
21
21
|
After search: persist under `{TASK}/research/` with a **provider label**; treat hits as candidates until corroborated (repo, test, or second source).
|
|
22
22
|
|
|
23
|
+
## Primary source preference
|
|
24
|
+
|
|
25
|
+
Prefer **primary sources** — official docs, source code, first-party API references, release notes, standards text. Mark blog posts, aggregators, and unverified second-hand summaries as **secondary** until corroborated against a primary source or the repo. This layers on top of "hits as candidates until corroborated": it ranks *which* candidates to trust first, and does not change the smart-search mandatory-first rule above.
|
|
26
|
+
|
|
27
|
+
## Prefer / Adapt / Own (code intelligence)
|
|
28
|
+
|
|
29
|
+
| Need | **Prefer** (Cursor native) | **Adapt** | **Own** (codegraph / MCP) |
|
|
30
|
+
| --- | --- | --- | --- |
|
|
31
|
+
| Exact literal / path | **Grep** (`rg`) | — | — |
|
|
32
|
+
| Named-symbol definition | **Grep → Read** | Path hints from semantic when file unknown | codegraph when trap/overload/blast context |
|
|
33
|
+
| IDE diagnostics | **ReadLints** | — | — |
|
|
34
|
+
| Conceptual discovery | **@codebase** / built-in semantic (Native) | **fast_context_search** (BYOK) | — |
|
|
35
|
+
| Caller chain / blast radius | Grep gap-fill | — | **codegraph** MCP |
|
|
36
|
+
| Cross-package trap / extension | Grep scoped | — | **codegraph** MCP |
|
|
37
|
+
| Raw LSP / GO_TO_DEFINITION | **Not in Agent tool table** — re-probe before claiming Prefer | — | codegraph product fallback |
|
|
38
|
+
|
|
39
|
+
**Rollback:** restore pre-P1 codegraph-first definition rows in this guide + `.cursor/rules/retrieval-routing.mdc`; keep codegraph MCP enabled.
|
|
40
|
+
|
|
41
|
+
**Evidence (2026-08-05):** `research/cursor-code-intel-external.md` — official Agent tools = search/read/edit (no LSP); semantic (@codebase) ≠ LSP; Agents Window LSP gap staff-confirmed on forum.
|
|
42
|
+
|
|
23
43
|
## Quick matrix
|
|
24
44
|
|
|
25
45
|
| Need | Tool | Notes |
|
|
26
46
|
| --- | --- | --- |
|
|
27
47
|
| Exact string / path / log line | **rg** (Grep) | Fast literal match in repo |
|
|
28
|
-
|
|
|
48
|
+
| Named-symbol definition | **Grep → Read** (Prefer); **codegraph** when trap/blast | Native first; structure when ambiguous |
|
|
49
|
+
| IDE diagnostics | **ReadLints** | Cursor-native linter/diagnostic surface |
|
|
50
|
+
| Symbol, callers, edit blast radius | **codegraph** MCP | Own layer: structure-first for caller/trap/extension intents |
|
|
29
51
|
| Unknown keywords, semantic discovery | **@codebase** (Cursor Native) / **fast-context** (Cursor++ BYOK) | Native: built-in semantic; BYOK: `fast_context_search` MCP (see `cursorEnv` in plans) |
|
|
30
52
|
| External / current facts | **smart-search-cli** | **Mandatory first** — built-in web tools are downgrade-only (see rule above) |
|
|
31
53
|
| Trellis durable docs | **artifact-search** | `search_artifacts.py` |
|
|
32
54
|
| Past sessions | **session-memory** | Historical; verify against tasks/spec |
|
|
33
55
|
| Intent hint for code questions | **router** | `route_codebase_retrieval.py` — plan JSON + `agentInstructions`; `--instructions` for steps only |
|
|
34
|
-
| Agent follows
|
|
56
|
+
| Agent follows retrieval policy on Cursor | **`.cursor/rules/retrieval-routing.mdc`** + **`route_codebase_retrieval.py`** | Rules enforce default tool order; `beforeSubmitPrompt` hook is telemetry-only (no plan injection); sessionStart is session-level orientation |
|
|
35
57
|
| Score collected evidence | **retrieval-pack** | `get_context.py --mode retrieval-pack` — does **not** search |
|
|
36
58
|
|
|
37
59
|
## Semantic routing (Cursor)
|
|
@@ -41,7 +63,7 @@ The planner emits **`platform-semantic`** with backend chosen by **`cursorEnv`**
|
|
|
41
63
|
- **native:** built-in `@codebase` / agent semantic search — **do not** use fast-context as Primary.
|
|
42
64
|
- **byok:** **fast-context MCP** (`fast_context_search`) — built-in semantic is not in the agent tool list.
|
|
43
65
|
|
|
44
|
-
Definition / reference jumps: **codegraph**
|
|
66
|
+
Definition / reference jumps (Agent): **Prefer Grep → Read** for named symbols; **codegraph** when trap/blast/ambiguity. **Not** raw LSP: `GO_TO_DEFINITION` absent from [Agent tool overview](https://cursor.com/docs/agent/overview.md) (2026-08-05). Semantic / `@codebase` is a separate Prefer path for concepts (embedding index), not LSP. IDE Editor F12 ≠ Agent tool routing.
|
|
45
67
|
|
|
46
68
|
## Token economy signals
|
|
47
69
|
|
|
@@ -92,7 +114,7 @@ When `smart-search doctor` is not ok or `run_smart_search.py` status is `not_con
|
|
|
92
114
|
|
|
93
115
|
**CLI discovery (Cursor):** `TRELLIS_SMART_SEARCH_COMMAND` / `smart_search.command` → PATH `smart-search` → project `node_modules/.bin/smart-search` (when installed as a dependency). Agent entrypoint is always `./.cstl/scripts/run_smart_search.py`.
|
|
94
116
|
|
|
95
|
-
**Research flags (smart-search ≥ 0.1.15):** pass through `run_smart_search.py` for `--intent deep-research`:
|
|
117
|
+
**Research flags (smart-search ≥ 0.2.0; flags also on 0.1.15+):** pass through `run_smart_search.py` for `--intent deep-research`:
|
|
96
118
|
|
|
97
119
|
| Flag | Values | Use |
|
|
98
120
|
| --- | --- | --- |
|
|
@@ -108,7 +130,7 @@ Research JSON may include `output_schema_version: 1` and structured `citations`
|
|
|
108
130
|
|
|
109
131
|
`route_codebase_retrieval.py` returns **intent + route suggestions** and **`agentInstructions`** (numbered steps with Cursor-native tool names). **codebase-evidence** is **candidate** until confirmed by Read/Git/tests.
|
|
110
132
|
|
|
111
|
-
On **Cursor**,
|
|
133
|
+
On **Cursor**, retrieval policy lives in **`.cursor/rules/retrieval-routing.mdc`** (`alwaysApply`) plus on-demand **`route_codebase_retrieval.py`**. The **`beforeSubmitPrompt`** hook is **telemetry-only** (no plan injection). `sessionStart` delivers session-level orientation (dashboard, workflow summary). Do **not** rely on end-of-turn **retrieval-pack** for plans — retrieval-pack **scores** collected evidence; it does not search.
|
|
112
134
|
|
|
113
135
|
### Result-layer ranking (B / E / D — REC-05)
|
|
114
136
|
|
|
@@ -120,7 +142,7 @@ After Grep/codegraph/semantic produce **path candidates**, reorder before choosi
|
|
|
120
142
|
| `trap-package-disambiguation` | Demote snapshot/registry/`src/agents/` trap paths unless Read confirms the asked layer. |
|
|
121
143
|
| `env-config-literal` | Prefer `scripts/`, `e2e/`, `bench/`, `test/` over generic `src/auth` / `src/paths`. |
|
|
122
144
|
|
|
123
|
-
- **Agent plans**: `render_agent_instructions` / `
|
|
145
|
+
- **Agent plans**: `render_agent_instructions` / `route_codebase_retrieval.py --instructions` append a **结果层排序** block when these intents appear.
|
|
124
146
|
- **Offline reorder**: `python ./.cstl/scripts/rank_retrieval_candidates.py --candidates fixtures.json --intents caller-chain --top-k 5 --pretty`
|
|
125
147
|
- **Library**: `common/retrieval_result_ranking.py` (Python mirror used by router and rank script).
|
|
126
148
|
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Test Discipline Guide(测试纪律)
|
|
2
|
+
|
|
3
|
+
> **Purpose**: 测试写作纪律 —— pre-agreed seams、垂直切片、三反模式、mock 边界,让写出来的测试值得保留。**纪律不是 TDD 要求**;写测试、读测试、评审测试时都适用,与是否测试先行无关。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Purpose — discipline, not TDD
|
|
8
|
+
|
|
9
|
+
本 guide 定义「测试写作纪律」:当测试存在时(新写、补写、评审、bug 回归落地),它们应当落在哪、验证什么、不做什么。纪律约束的是测试**质量**,不是测试**时序**:
|
|
10
|
+
|
|
11
|
+
- **不要求 red-before-green**。可以先写测试(test-first 是可选的节奏),也可以实现后补测试——纪律在两种时序下同样适用。
|
|
12
|
+
- **不强制 TDD 循环**。本 guide 不定义 red → green → refactor 流程;不设「每个函数必须单测」门槛。
|
|
13
|
+
- 与 [Verification Strength Guide](./verification-strength-guide.md) 兼容:验证**强度**(任务 closeout 要验多深)≠ red-green 仪式;本 guide 管的是「测试怎么写才值得保留」。
|
|
14
|
+
|
|
15
|
+
> 一句话:**先确认测点(seam),再写测试;测试验公共行为,不验实现。**
|
|
16
|
+
|
|
17
|
+
## 2. Non-goals
|
|
18
|
+
|
|
19
|
+
- **不是 TDD 手册**:不要求测试先行,不要求红-绿循环,不把 red-before-green 写成强制流程。
|
|
20
|
+
- **不选型**:不规定 pytest 以外的框架,不做 mock 库选型。
|
|
21
|
+
- **不替代 Verification Strength Guide**:验证强度(closeout 深度 / false-green 探针)由该 guide 管,本 guide 只管测试写作本身。
|
|
22
|
+
- **不替代 Debug Loop Guide Phase 5**:bug 驱动的回归落地由 debug-loop 管,本 guide 只定义何为 good seam(见 §9)。
|
|
23
|
+
|
|
24
|
+
## 3. What a good test is
|
|
25
|
+
|
|
26
|
+
好测试的判据,对每次测试写作生效:
|
|
27
|
+
|
|
28
|
+
- **通过公共 interface 验行为,不验实现细节**。module 可以完全重写,测试不该跟着改;测试关心调用者能获得什么行为,不关心内部怎么拼。
|
|
29
|
+
- **读起来像规格**。测试名描述能力(「用户可以用有效购物车结账」),读者从测试就能看出 module 支持什么。
|
|
30
|
+
- **耐重构**。重构后行为不变,测试仍绿;只有行为真正变化时才变红。
|
|
31
|
+
- **期望值来自独立事实源**。已知字面量、手算样例、规格值——不是用实现同款方式重算(见 §6 tautological)。
|
|
32
|
+
|
|
33
|
+
## 4. Seams(pre-agreed)
|
|
34
|
+
|
|
35
|
+
**seam**(词汇与 CONTEXT.md architecture 段一致):*不改动原处即可改变行为的位置*。测试在 seam 处通过 interface 观察行为,绝不伸手进内部。
|
|
36
|
+
|
|
37
|
+
**只在 pre-agreed seam 写测试。** 写任何测试之前:
|
|
38
|
+
|
|
39
|
+
1. **列出待测 seam 清单**:要测哪些 module 的哪个 interface、每条验什么行为。
|
|
40
|
+
2. **与用户确认**。未确认的 seam 不写测试。
|
|
41
|
+
3. 确认时按此排序:**优先既有 seam**(已有接口 / 既有测试点,不为测试新建结构);**尽量高位 seam**(越接近用户行为越好——一条高位测试覆盖多个低位实现);**少而精**(宁可一条高位测试,不要十条内部断言)。
|
|
42
|
+
|
|
43
|
+
你不可能测完一切——预先同意 seam,是把测试力气花在关键路径和复杂逻辑上,而不是每个边角。
|
|
44
|
+
|
|
45
|
+
> 问句:「公共 interface 是什么?我们要测哪些 seam?」——接口形状本身有疑问时(module 多深、seam 该在哪),先做设计,再定测点。
|
|
46
|
+
|
|
47
|
+
## 5. Vertical slices(tracer bullets)
|
|
48
|
+
|
|
49
|
+
**一测 → 一段最小实现 → 重复**:
|
|
50
|
+
|
|
51
|
+
1. 一个 seam、一条测试(tracer bullet)。
|
|
52
|
+
2. 只写让这条测试通过的最小实现。
|
|
53
|
+
3. 重复,让每条新测试回应上一条循环学到的形状。
|
|
54
|
+
|
|
55
|
+
**禁止 horizontal bulk**——先写完全部测试再实现。横向批量的危害:测试验证的是**想象的行为**(测的是形状而不是用户行为)、对真实变化不敏感、实现还没理解就锁死了测试结构。
|
|
56
|
+
|
|
57
|
+
垂直切片在测试**写作**上同样成立:不要在动手前批量铺测试,一条一条来。
|
|
58
|
+
|
|
59
|
+
## 6. Anti-patterns(三反模式)
|
|
60
|
+
|
|
61
|
+
### Implementation-coupled(实现耦合)
|
|
62
|
+
|
|
63
|
+
mock 内部协作对象、测私有方法、或旁路验证(绕过 interface 直接查库 / 读内部状态)。
|
|
64
|
+
|
|
65
|
+
- 识别信号:重构后测试变红但行为没变;测试名描述 HOW 不描述 WHAT;断言调用次数 / 调用顺序。
|
|
66
|
+
- 反例:`create_user` 后直接查库验入库——应通过 interface 验「创建后能取回」。
|
|
67
|
+
- 修正:回到 §3——只通过公共 interface 观察行为。
|
|
68
|
+
|
|
69
|
+
### Tautological(同义反复)
|
|
70
|
+
|
|
71
|
+
期望值用与实现相同的方式重算,passes by construction——测试永远不可能与代码不一致,因为它复述了代码。
|
|
72
|
+
|
|
73
|
+
- 识别信号:期望值是 reduce / 拼接 / 同式重算;快照由实现同款手工推出;常量断言等于它自己。
|
|
74
|
+
- 反例:`expect(total([10, 5])).toBe(items.reduce(...))`——期望值就是实现。
|
|
75
|
+
- 修正:期望值必须来自独立事实源——已知字面量(`expect(total([10, 5])).toBe(15)`)、手算样例、规格值。
|
|
76
|
+
|
|
77
|
+
### Horizontal slicing(横向切片)
|
|
78
|
+
|
|
79
|
+
先写全部测试再实现;按层横切而不是按用户行为竖切。
|
|
80
|
+
|
|
81
|
+
- 识别信号:测试一次性铺满所有层级(API 层全部 → 服务层全部 → …);测试对象是「形状」而非行为;实现未动时测试结构已锁定。
|
|
82
|
+
- 修正:回到 §5 垂直切片。
|
|
83
|
+
|
|
84
|
+
## 7. Mock boundaries
|
|
85
|
+
|
|
86
|
+
**只在系统边界 mock**:
|
|
87
|
+
|
|
88
|
+
- 外部 API(支付、邮件等)
|
|
89
|
+
- DB(**优先用测试库**,mock DB 是退路)
|
|
90
|
+
- 时间 / 随机性
|
|
91
|
+
- 文件系统(视情况)
|
|
92
|
+
|
|
93
|
+
**不 mock**:
|
|
94
|
+
|
|
95
|
+
- 自己的 module / 内部协作对象
|
|
96
|
+
- 任何我们控制的东西
|
|
97
|
+
|
|
98
|
+
为可 mock 性设计接口:
|
|
99
|
+
|
|
100
|
+
- **DI 优于内部 `new`**:外部依赖从参数传入,而不是在实现里创建:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
# 易 mock:依赖注入
|
|
104
|
+
def process_payment(order, payment_client):
|
|
105
|
+
return payment_client.charge(order.total)
|
|
106
|
+
|
|
107
|
+
# 难 mock:实现内部创建
|
|
108
|
+
def process_payment(order):
|
|
109
|
+
client = PaymentClient(os.environ["PAYMENT_KEY"])
|
|
110
|
+
return client.charge(order.total)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
- **SDK 式接口优于通用 fetcher**:每个外部操作用独立函数(`get_user(id)` / `create_order(data)`),而不是一个带条件分支的通用 `fetch(endpoint, opts)`。每个 mock 返回一种确定形状,测试设置里没有条件逻辑,也容易看出测试走了哪个端点。
|
|
114
|
+
|
|
115
|
+
## 8. Relation to verification-strength-guide
|
|
116
|
+
|
|
117
|
+
- Verification Strength Guide 管验证**强度**:任务 closeout 要验多深、false-green 探针,且明确 **not TDD**(§1 Non-goals:不产品化 red-green 仪式、无 per-function 单测门槛)。
|
|
118
|
+
- 本 guide 管测试**写作质量**:测试存在时,落在 pre-agreed seam、验公共行为、避开三反模式。
|
|
119
|
+
- 二者正交、兼容:按验证强度选验证深度;按本 guide 写测试。**验证强度 ≠ red-green 仪式。**
|
|
120
|
+
|
|
121
|
+
## 9. Relation to debug-loop Phase 5(衔接不吞并)
|
|
122
|
+
|
|
123
|
+
[Debug Loop Guide](./debug-loop-guide.md) Phase 5 的回归是 **bug 驱动**:把最小复现冻结成测试或可重复命令,且必须落在 **correct seam**(在真实调用点复现真实 bug 模式)。
|
|
124
|
+
|
|
125
|
+
- **bug 回归走 debug-loop**:Phase 5 决定「把这个 bug 锁在哪个 seam」,本 guide 不接管闭环流程。
|
|
126
|
+
- **通用测试写作走本 guide**:新功能、补测、评审由本 guide 管(pre-agreed seam、反模式、mock 边界)。
|
|
127
|
+
- 衔接点:Phase 5 判定 correct seam 时,引用的正是本 guide 的 good seam 概念与反模式——**衔接不吞并**:bug 驱动回归 ≠ 通用测试写作,两者各有入口,互不替代。
|
|
128
|
+
|
|
129
|
+
## 10. Checklist before writing tests
|
|
130
|
+
|
|
131
|
+
写测试前确认:
|
|
132
|
+
|
|
133
|
+
- [ ] seam 清单已列出并与用户确认(**未确认的 seam 不写测试**)
|
|
134
|
+
- [ ] 优先既有 seam / 高位 seam / 少而精
|
|
135
|
+
- [ ] 测试通过公共 interface 验行为(不是私有方法、不是内部协作对象)
|
|
136
|
+
- [ ] 期望值来自独立事实源(已知字面量 / 样例 / 规格),不是实现同款重算
|
|
137
|
+
- [ ] mock 只在系统边界;自己的 module 不 mock;依赖经 DI 注入
|
|
138
|
+
- [ ] 一次一条垂直切片(一测 → 最小实现 → 重复),不做横向批量
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Verification Strength Guide
|
|
2
|
+
|
|
3
|
+
> **Purpose**: Define **how deeply** cstl tasks must be verified before closeout — graded by task risk (Lite / Full / Parent), **not** TDD ceremony.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Non-goals
|
|
8
|
+
|
|
9
|
+
- **No TDD productization** — cstl does not require red-green-refactor loops, "write tests first" gates, or per-function unit test mandates.
|
|
10
|
+
- **No per-task full-suite burden** — Lite tasks must not be forced through architecture review or whole-repo CI.
|
|
11
|
+
- **No replacement for project test frameworks** — cstl validation checks **task evidence** in `verify.md` and configured quality gates; it does not run or replace your project's test runner.
|
|
12
|
+
- **No test-writing mandate** — how to write good tests (pre-agreed seams, anti-patterns, mock boundaries) lives in the [Test Discipline Guide](./test-discipline-guide.md); verification strength is orthogonal to test-writing style.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 2. Two-axis model (verification strength, not TDD)
|
|
17
|
+
|
|
18
|
+
### Axis A — Task Ladder closeout profile
|
|
19
|
+
|
|
20
|
+
Inferred by `task.py` from artifact presence and `task.json` meta. Determines **minimum evidence** before archive or child integration.
|
|
21
|
+
|
|
22
|
+
| Closeout profile | Trigger (existing logic) | Minimum verification depth |
|
|
23
|
+
| --- | --- | --- |
|
|
24
|
+
| **lite** | No `design.md`+`implement.md`; or meta marks lite | PRD AC mapping + focused validation + acceptance + durable-learning decision |
|
|
25
|
+
| **full** | Has `design.md` + `implement.md` | Lite depth + DSC validation + **check evidence** + **reviewed change-set** + configured reviewer gates |
|
|
26
|
+
| **parent** | `task.json.children` non-empty | Each child integrated/cancelled + parent integration evidence + integration-review gate |
|
|
27
|
+
|
|
28
|
+
**High-risk upgrade (normative):** scope touching framework semantics, cross-file workflow, `verification_profile`, or capabilities should **Lite → Full** per `workflow.md` Task Ladder rules.
|
|
29
|
+
|
|
30
|
+
### Axis B — `verification_profile` (reviewer gate strictness)
|
|
31
|
+
|
|
32
|
+
Declared in `implement.md` Development Strategy Contract. Guide narrative: **验证强度** — never "TDD tier".
|
|
33
|
+
|
|
34
|
+
| Profile | Default enabled gates | Strength meaning |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| **standard** | requirements-review, code-review | Default Full/Child: planning artifacts + change review + validation/check evidence |
|
|
37
|
+
| **strict** | same as standard (reserved for stricter archive signals) | High-risk Full default this wave |
|
|
38
|
+
| **architecture** | + architecture-review | Cross-layer / contract / template / runtime changes |
|
|
39
|
+
|
|
40
|
+
Details: `task_gates.py` → `PROFILE_DEFAULT_GATES`.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 3. Minimum validation checklist by closeout profile
|
|
45
|
+
|
|
46
|
+
### Lite
|
|
47
|
+
|
|
48
|
+
- [ ] Focused validation on **touched behavior** (command + result in `verify.md`)
|
|
49
|
+
- [ ] `python ./.cstl/scripts/task.py validate <task>`
|
|
50
|
+
- [ ] Final acceptance mapped to PRD AC
|
|
51
|
+
- [ ] Durable-learning decision line (see [Durable Learning Decision Guide](./durable-learning-decision-guide.md))
|
|
52
|
+
|
|
53
|
+
**Example `verify.md` lines:**
|
|
54
|
+
|
|
55
|
+
```markdown
|
|
56
|
+
Validation: `python -m py_compile src/foo.py` — exit 0
|
|
57
|
+
Acceptance: prd AC 1–3 satisfied; typo fix verified in editor
|
|
58
|
+
Durable learning decision: no durable learning — one-off content fix
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Full
|
|
62
|
+
|
|
63
|
+
All Lite items, plus:
|
|
64
|
+
|
|
65
|
+
- [ ] Validation commands from `implement.md` executed; results recorded
|
|
66
|
+
- [ ] `Check evidence:` or `cstl-check evidence:` — inline skill or agent review completed
|
|
67
|
+
- [ ] `Reviewed change-set:` or `Git diff ref:` — identity of reviewed diff
|
|
68
|
+
- [ ] Required gates recorded via `task.py record-gate` when contract enables them
|
|
69
|
+
|
|
70
|
+
**Example:**
|
|
71
|
+
|
|
72
|
+
```markdown
|
|
73
|
+
Validation: probe matrix 4/4 PASS (see research/probe-results.md)
|
|
74
|
+
Check evidence: cstl-check skill — spec compliance + py_compile
|
|
75
|
+
Reviewed change-set: git diff main..HEAD — 8 files in .cstl/spec + scripts
|
|
76
|
+
Acceptance: prd AC 1–5 mapped below
|
|
77
|
+
Durable learning decision: no durable learning
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Parent
|
|
81
|
+
|
|
82
|
+
All structural children `integrated` or `cancelled`, plus:
|
|
83
|
+
|
|
84
|
+
- [ ] `Integration evidence:` in parent `verify.md`
|
|
85
|
+
- [ ] `integration-review` gate when parent contract requires it
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 4. Choosing `verification_profile`
|
|
90
|
+
|
|
91
|
+
| Situation | Suggested profile |
|
|
92
|
+
| --- | --- |
|
|
93
|
+
| Single-file / local fix, Lite ladder | N/A (lite closeout; gates minimal) |
|
|
94
|
+
| Full task, normal feature | `standard` |
|
|
95
|
+
| High-risk Full (hooks, gates, templates, runtime) | `strict` or `architecture` |
|
|
96
|
+
| Cross-layer contract / framework semantics | `architecture` |
|
|
97
|
+
|
|
98
|
+
Set in `implement.md`:
|
|
99
|
+
|
|
100
|
+
```yaml
|
|
101
|
+
verification_profile: standard
|
|
102
|
+
quality_gates:
|
|
103
|
+
mode: explicit
|
|
104
|
+
enabled: [requirements-review, code-review]
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 5. `verify.md` signal line format (CLI-aligned)
|
|
110
|
+
|
|
111
|
+
The CLI uses regex to detect **substantive** evidence. Placeholder values (`TBD`, `N/A`, `待定`, `-`, `...`) are rejected.
|
|
112
|
+
|
|
113
|
+
| Signal | Example lines (any one match) |
|
|
114
|
+
| --- | --- |
|
|
115
|
+
| Validation | `Validation:`, `Validation commands:`, `Validation results:` |
|
|
116
|
+
| Check evidence | `Check evidence:`, `cstl-check evidence:` |
|
|
117
|
+
| Acceptance | `Acceptance:`, `Final acceptance:`, `Accepted by user:` |
|
|
118
|
+
| Durable learning | `Durable learning decision:`, `no durable learning`, `Spec update evidence:` |
|
|
119
|
+
| Integration | `Integration evidence:`, `Final integration:` |
|
|
120
|
+
| Reviewed change-set | `Reviewed change-set:`, `Git diff ref:`, `Changeset:` |
|
|
121
|
+
|
|
122
|
+
**Not sufficient alone:**
|
|
123
|
+
|
|
124
|
+
- `python ./.cstl/scripts/task.py validate` passing JSONL schema — **does not** prove task acceptance
|
|
125
|
+
- Long log dumps without structured signal lines
|
|
126
|
+
- Checkbox ticks in PRD without `verify.md` validation mapping
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 6. False-green detection
|
|
131
|
+
|
|
132
|
+
### Existing CLI guards
|
|
133
|
+
|
|
134
|
+
| Failure mode | Mechanism |
|
|
135
|
+
| --- | --- |
|
|
136
|
+
| Placeholder validation | `PLACEHOLDER_VALUES_RE` in `task_gates.py` |
|
|
137
|
+
| Missing archive signals | `verify_evidence_status()` at archive / `record-gate` |
|
|
138
|
+
| PRD AC all placeholder | `_prd_requirements_review_errors` at start-execution |
|
|
139
|
+
| Gate PASS without evidence | `record-gate` rejects substantive-missing verify |
|
|
140
|
+
|
|
141
|
+
### Repeatable probe
|
|
142
|
+
|
|
143
|
+
Run fixture matrix against shared logic (no second rule set):
|
|
144
|
+
|
|
145
|
+
```powershell
|
|
146
|
+
python ./.cstl/scripts/verify_evidence_probe.py --fixture <path> --profile lite|full|parent --expect pass|fail
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Fixtures: `.cstl/tasks/08-06-cstl-p0-verify-capability/research/verification-probes/`
|
|
150
|
+
|
|
151
|
+
| Fixture | Intent | lite | full |
|
|
152
|
+
| --- | --- | --- | --- |
|
|
153
|
+
| `shallow-placeholder.md` | Placeholder-only verify | FAIL | FAIL |
|
|
154
|
+
| `lite-sufficient.md` | Minimal valid Lite | PASS | FAIL (missing check + changeset) |
|
|
155
|
+
| `full-sufficient.md` | Valid Full closeout | PASS | PASS |
|
|
156
|
+
| `overkill-noise.md` | Verbose logs, no signals | FAIL | FAIL |
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 7. Shallow vs overkill (quick reference)
|
|
161
|
+
|
|
162
|
+
| Scenario | Too shallow (should block) | Overkill (non-goal) |
|
|
163
|
+
| --- | --- | --- |
|
|
164
|
+
| Lite typo fix | "Looks good" with no `Validation:` line | architecture-review + full-repo test suite |
|
|
165
|
+
| Full hook change | `py_compile` only, no `Reviewed change-set:` | Mandate new unit test per function (TDD) |
|
|
166
|
+
| Parent integrate child | Child verify still placeholder | Full E2E per child |
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 8. Integration with cstl-check / record-gate / archive
|
|
171
|
+
|
|
172
|
+
```text
|
|
173
|
+
Phase 2 Execute → cstl-check (skill/agent) → verify.md evidence
|
|
174
|
+
Phase 3.1 Verify → record-gate (non-baseline) → archive --check
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
- **cstl-check**: review against spec + task artifacts; fix in-contract defects; write human-readable evidence **before** `record-gate`.
|
|
178
|
+
- **record-gate**: machine state only; requires substantive `verify.md` for PASS/SKIPPED.
|
|
179
|
+
- **archive**: `verify_evidence_status()` must pass for profile; Full also needs gate readiness.
|
|
180
|
+
|
|
181
|
+
Workflow cross-ref: Phase 3.1 Quality verification in `workflow.md`.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
**Core principle:** Match verification **strength** to task **risk** — enough to catch false greens, never enough to become TDD theater.
|