flower-trellis 0.6.8-beta.1 → 0.6.8-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.
- package/enhancements/0.6/.agents/skills/trellis-auto-loop/SKILL.md +10 -6
- package/enhancements/0.6/.agents/skills/trellis-auto-loop/references/artifact-recovery.md +38 -0
- package/enhancements/0.6/.agents/skills/trellis-check-all/SKILL.md +2 -2
- package/enhancements/0.6/.agents/skills/trellis-check-all/references/fallback-findings.md +1 -1
- package/enhancements/0.6/.agents/skills/trellis-check-all/references/reporting-and-disposition.md +31 -39
- package/enhancements/0.6/.agents/skills/trellis-push/references/output-templates.md +4 -3
- package/enhancements/0.6/.agents/skills/trellis-route/SKILL.md +2 -0
- package/enhancements/0.6/.agents/skills/trellis-route/scripts/route_state.py +75 -31
- package/enhancements/0.6/.agents/skills/trellis-task-brief/SKILL.md +10 -2
- package/enhancements/0.6/.claude/skills/trellis-auto-loop/SKILL.md +10 -6
- package/enhancements/0.6/.claude/skills/trellis-auto-loop/references/artifact-recovery.md +38 -0
- package/enhancements/0.6/.claude/skills/trellis-check-all/SKILL.md +2 -2
- package/enhancements/0.6/.claude/skills/trellis-check-all/references/fallback-findings.md +1 -1
- package/enhancements/0.6/.claude/skills/trellis-check-all/references/reporting-and-disposition.md +31 -39
- package/enhancements/0.6/.claude/skills/trellis-push/references/output-templates.md +4 -3
- package/enhancements/0.6/.claude/skills/trellis-route/SKILL.md +2 -0
- package/enhancements/0.6/.claude/skills/trellis-route/scripts/route_state.py +75 -31
- package/enhancements/0.6/.claude/skills/trellis-task-brief/SKILL.md +10 -2
- package/enhancements/0.6/overrides/conflicts.json +8 -2
- package/enhancements/0.6/overrides/patches/skills/trellis-continue/task-progress-recovery/content.md +3 -1
- package/enhancements/0.6/overrides/patches/skills/trellis-update-spec/autonomous-evaluation/content.md +2 -2
- package/enhancements/0.6/overrides/patches/workflow/phase-ownership/phase-2-check-content.md +1 -1
- package/enhancements/0.6/scripts/auto_loop.py +461 -98
- package/enhancements/MANIFEST.json +2 -2
- package/package.json +3 -3
- package/src/assets/flower_session_start.py +3 -2
|
@@ -12,8 +12,8 @@ description: "启动、恢复和推进 Trellis 自动任务循环。用于用户
|
|
|
12
12
|
- 仅在用户明确要求 auto-loop、自动跑到底、goal-like 或继续既有 run 时使用;普通实现请求不能自动升级。
|
|
13
13
|
- 用户发出启动指令即授权本次 `commit-only` run。prepare 完成后不再确认 manifest,也不逐任务执行 `confirm_brief`。
|
|
14
14
|
- 新 run 先 prepare 全部显式任务,Open Questions 全部收敛后才进入 running。running 中不再询问 route、planning 或普通 Check-All 停止边界。
|
|
15
|
-
- 每个 action 完成后,必须用同名 `record --action ...`
|
|
16
|
-
- `record` 返回 `status=retryable`
|
|
15
|
+
- 每个 action 完成后,必须用同名 `record --action ...` 精确回写;record 成功后立即 `next`。不得根据聊天摘要手改 runtime 或跳步。
|
|
16
|
+
- `record` 返回 `status=retryable` 时不得运行 `next`,必须按返回指令在同一个 outstanding action 内纠正并重录;恢复诊断的 owner 见下方 Action 内恢复。
|
|
17
17
|
- 本地提交是自动终点。不得 push、merge、release、deploy、finish-work 或 archive;runner 在 item 本地提交成功后把该任务写入本地完成态(`status=completed` + `completedAt`),归档仍需用户显式执行。
|
|
18
18
|
- 任务顺序只决定稳定调度顺序,不隐含依赖。依赖必须通过 `--depends-on dependent=dependency` 明确传入或由 planning artifacts 明确声明。
|
|
19
19
|
- 任务级失败只阻塞自身及显式依赖项;独立任务继续。fix/recheck、planning repair 与安全的 commit-only repair 各最多 3 轮,队列结束后不自动执行第二遍恢复扫描。
|
|
@@ -67,7 +67,7 @@ readiness 的 `repairable` 仅适用于不改变目标、可由仓库证据确
|
|
|
67
67
|
|
|
68
68
|
## Autonomous Decisions
|
|
69
69
|
|
|
70
|
-
满足任务目标内、仅影响本地代码、可逆且可验证时,AI可自主选择推荐方案。作出选择后必须先记录,再继续修改或 record;会修改 planning/handoff 时,`--file` 必须列出全部目标 artifact:
|
|
70
|
+
满足任务目标内、仅影响本地代码、可逆且可验证时,AI可自主选择推荐方案。作出选择后必须先记录,再继续修改或 record;会修改 planning/handoff 时,`--task-file` 或完整 `--file` 必须列出全部目标 artifact:
|
|
71
71
|
|
|
72
72
|
```bash
|
|
73
73
|
python3 ./.trellis/scripts/auto_loop.py decide \
|
|
@@ -79,11 +79,11 @@ python3 ./.trellis/scripts/auto_loop.py decide \
|
|
|
79
79
|
[--evidence "<证据>" ...] \
|
|
80
80
|
--risk low|medium \
|
|
81
81
|
--confidence low|medium|high \
|
|
82
|
-
[--requirement <id> ...] [--file <repository>::<path> ...] \
|
|
82
|
+
[--requirement <id> ...] [--task-file <name> ...] [--file <repository>::<path> ...] \
|
|
83
83
|
[--verification "<验证摘要>"]
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
-
决策写入 runtime 摘要和任务 `decisions.jsonl`,只保存结论与证据,不保存思维链。下一次同任务 action record 会消费该决策:列明的 planning/handoff 变化生成绑定 decision ID 的 manifest revision;Check record 中其它变化进入有限自纠,其它 action
|
|
86
|
+
决策写入 runtime 摘要和任务 `decisions.jsonl`,只保存结论与证据,不保存思维链。下一次同任务 action record 会消费该决策:列明的 planning/handoff 变化生成绑定 decision ID 的 manifest revision;Check record 中其它变化进入有限自纠,其它 action 的确定路径错误先进入恢复诊断,未知或越界漂移仍按 `artifact-drift` 阻塞。
|
|
87
87
|
|
|
88
88
|
以下事项不得用 `decide`,必须 blocked:
|
|
89
89
|
|
|
@@ -95,6 +95,10 @@ python3 ./.trellis/scripts/auto_loop.py decide \
|
|
|
95
95
|
- 明显改变任务目标或业务规则且仓库没有倾向证据。
|
|
96
96
|
- `Open Questions` 中人工保留的任何选择。
|
|
97
97
|
|
|
98
|
+
## Action 内恢复
|
|
99
|
+
|
|
100
|
+
`next` 保留原 action 和文档基线,不消费 pending。收到 `artifact-recovery-required` 或 `artifact-recovery-failed` 时,必须读取 [恢复协议](references/artifact-recovery.md),同轮完成诊断、纠正、`reconcile` 校验并继续原 action。初次诊断不计数,最多三次实际纠正,第三次仍可成功;不要求用户回复“继续”。
|
|
101
|
+
|
|
98
102
|
## Running Actions
|
|
99
103
|
|
|
100
104
|
| action | 主 agent 行为 | 成功 record |
|
|
@@ -161,7 +165,7 @@ python3 ./.trellis/scripts/auto_loop.py status [--verbose]
|
|
|
161
165
|
python3 ./.trellis/scripts/auto_loop.py stop --reason "<原因>"
|
|
162
166
|
```
|
|
163
167
|
|
|
164
|
-
默认使用紧凑输出;只有诊断 manifest、dirty、漂移、依赖链或决策详情时加 `--verbose`。`retryable` 不是终态,由 agent
|
|
168
|
+
默认使用紧凑输出;只有诊断 manifest、dirty、漂移、依赖链或决策详情时加 `--verbose`。`retryable` 不是终态,由 agent 按对应通道在同一 outstanding action 内立即自纠;`completed_with_blocked` 才是本次 run 的可审计终态,后续恢复由用户显式调用 `retry-blocked`。
|
|
165
169
|
|
|
166
170
|
## Run 收尾交接
|
|
167
171
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Action 内恢复与三轮纠正
|
|
2
|
+
|
|
3
|
+
收到 `status=retryable reason=artifact-recovery-required|artifact-recovery-failed` 时读取本文件,并在同轮执行纠正。它是原 action 的恢复通道,不是新的业务 action,也不要求用户回复“继续”。
|
|
4
|
+
|
|
5
|
+
## 登记与恢复
|
|
6
|
+
|
|
7
|
+
- 当前任务四文档优先用 `decide --task-file prd.md|design.md|implement.md|brief.md`,可重复。普通 `--file` 仍是仓库相对路径或 `<repository>::<path>`,可登记尚未创建的代码文件;裸文档名不自动解释为任务路径。
|
|
8
|
+
- 无效路径被拒绝时不会写入 decision/pending/manifest;有可信原 action 的确定 basename 错误会返回恢复诊断。根同名文件、未知仓库、越界、软链或 protected 冲突不能猜测修正。
|
|
9
|
+
- `next` 重放同一 outstanding action、issued_at、深度和原文档基线。正确 pending 覆盖的修改可以恢复执行,但只能由后续真实 `record` 消费 pending 和重绑 manifest。
|
|
10
|
+
- 原 Check 只有 implement/brief 的待申报 DOC 变化时,恢复后仍按 Check 的 DOC 资格与精确文件申报规则回写;不能把恢复查询视为接受内容。
|
|
11
|
+
|
|
12
|
+
## Agent 纠正步骤
|
|
13
|
+
|
|
14
|
+
1. 读取诊断的 `recovery_id`、`source`、原 action、原 decision ID、`baseline`、`candidates`、`changed` 和 `attempts`,结合原 `decisions.jsonl`、任务 artifacts、真实 diff 和执行证据核实归属。文件集合吻合不能代替需求和语义审查。
|
|
15
|
+
2. 对已证明的 basename 错登记,提交诊断中的精确一对一映射。旧 pending 的纠正只追加普通决策审计并改文件键,保留原 choice、requirements、risk 与修改前 baseline。初始 decide 被拒绝时,纠正成功后必须重新调用原 decide,登记成功才编辑。
|
|
16
|
+
3. 存在额外误改时,先保全新增记录,仅撤回能证明由本 action 造成的误改,再提交校验。runner 不覆盖文件;不得恢复用户、外部会话或来源不明的修改。
|
|
17
|
+
4. 无法安全归因、原语义不足、涉及 Open Questions、需求扩张或风险黑名单时提交 `blocked`。
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
python3 ./.trellis/scripts/auto_loop.py reconcile \
|
|
21
|
+
--run-id <run> --task <task> \
|
|
22
|
+
--recovery-id <诊断ID> --attempt-id <本次唯一ID> \
|
|
23
|
+
--result ok|failed|blocked --summary "<纠正结论>" \
|
|
24
|
+
[--evidence "<已读取的证据>" ...] \
|
|
25
|
+
[--file-map '<旧唯一键>=<当前任务同名文档唯一键>' ...]
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
runner 会重读文件并验证映射、基线和 protected 边界,不能仅凭 `--result ok` 放行。`reconciled` 后按返回指令在同轮继续原 action 或重试原 decide,提交原 action 的真实结果;纠正不能代表 Check 通过、实现完成或提交成功。非 Check record 若返回恢复诊断,也必须先纠正,再重新提交原真实 record,不能直接 next 跳过。
|
|
29
|
+
|
|
30
|
+
## 预算与重复恢复
|
|
31
|
+
|
|
32
|
+
初次发现为 0 次;next/status/resume、压缩恢复和同尝试同载荷重放不计数。前三次以明确提交的实际纠正计数:前两次失败继续同轮纠正,第三次可成功,第三次失败才终态 blocked。更换诊断或错误路径不能重置同一 action 的预算。
|
|
33
|
+
|
|
34
|
+
同一个 attempt-id 仅用于重放完全相同的请求;载荷变化用新 ID。回执丢失后重放原请求,日志已写但 runtime 未写也不会重复追加决策。观察值变化会拒绝沿用旧回执,按 runner 指令重新诊断;不手写 runtime 或删审计来“修复”状态。
|
|
35
|
+
|
|
36
|
+
既有 Check `status=retryable reason=artifact-drift` 继续由原 Check 重录通道负责:不调用 next/reconcile 获取第二套预算,保留原 3 次 retryable 后第 4 次 blocked 的规则。next 已建立的恢复诊断先完成,再允许原 record;一个错误只走一个通道。fix/recheck、commit repair 和部分成功提交仍由原 owner 管理。
|
|
37
|
+
|
|
38
|
+
恢复期 run/item 仍 running,依赖项不会提前失败。未知漂移、无可信基线、受保护内容变化或预算耗尽仍按原阻塞和依赖传播规则处理;独立任务继续。历史终态 run 不自动复活,仍需用户显式 retry-blocked。
|
|
@@ -30,7 +30,7 @@ description: "统一 Check-All:按 requested/effective depth 路由 light/full
|
|
|
30
30
|
1. **默认 audit-only collect-all**:可读取、搜索和运行无业务写入的验证;普通代码、配置、测试和任务规格语义不得直接修复。
|
|
31
31
|
2. **唯一自修例外**:低风险事实漂移进入 `DOC-*` 通道,按 `references/document-drift-auto-remediation.md` 的白名单、黑名单和写入时机处理。
|
|
32
32
|
3. **分类先于严重度**:读取 `references/fallback-findings.md`;主路径错误和非兜底契约违背进入 `CHK-*`,fail-closed、异常输入、失败降级和防御性保护缺口进入 `FBK-*`。契约证据影响严重度,不改变兜底根因归属。
|
|
33
|
-
4. **处置只确认一次**:统一报告后选择 `CHK-*` / `FBK-*` 修复范围或接受风险;`修复全部`
|
|
33
|
+
4. **处置只确认一次**:统一报告后选择 `CHK-*` / `FBK-*` 修复范围或接受风险;`修复全部` 覆盖两类。接受后按 reporting reference 简短确认,保留发现记录,不重复展开未变化的已接受问题。
|
|
34
34
|
5. **共享验证**:两个 profile 共用 `references/verification.md`;同一追踪与有效验证证据跨维度复用,检查保持只读。
|
|
35
35
|
6. **真正阻塞才中途暂停**:业务规划冲突、前提失效,或当前结论必需验证涉及未授权生产/外部/破坏性副作用时暂停;发布后验收只记 `[上线后验证]`,不执行、不阻断。
|
|
36
36
|
|
|
@@ -85,7 +85,7 @@ untracked helper 只存游标:findings 或新编辑回 `implement`;通过且
|
|
|
85
85
|
|
|
86
86
|
### Step 4:统一报告与分流
|
|
87
87
|
|
|
88
|
-
读取 `references/reporting-and-disposition.md
|
|
88
|
+
读取 `references/reporting-and-disposition.md`,按其首次报告、接受后增量展示与分流规则输出;默认不新建报告文件,落盘例外由该 reference 定义。
|
|
89
89
|
|
|
90
90
|
---
|
|
91
91
|
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
- `CHK-*` 与 `FBK-*` 独立编号,修复/重检循环保留原 ID;两类都按实际影响分配 P0/P1/P2。
|
|
70
70
|
- `修复全部` 覆盖两类问题;精确修复可混合 ID,例如 `修复 CHK-001,FBK-002`。
|
|
71
71
|
- 用户可以明确接受当前报告中任一 `CHK-*` 或 `FBK-*` 的风险而不修复;问题仍保留原通道、严重度和证据。
|
|
72
|
-
- 接受当前报告全部风险覆盖全部 `CHK-*` / `FBK-*`,包括 P0
|
|
72
|
+
- 接受当前报告全部风险覆盖全部 `CHK-*` / `FBK-*`,包括 P0,无固定句式;部分接受须唯一定位。报告或范围不清才追问;接受有效性与增量展示统一按 `reporting-and-disposition.md`,不因无关 diff 变化失效。
|
|
73
73
|
- `strict pass` 仍要求剩余 `CHK-*` 与 `FBK-*` 均为 0;全部剩余问题被有效接受且无阻塞、部分验证或其它实质风险时,使用“已接受风险通过”。
|
|
74
74
|
- 未处置 `CHK-*` / `FBK-*`、阻断型部分验证或阻塞会阻断;`[上线后验证]` 不阻断。auto-loop 不得接受风险,须两类问题为 0 且无阻断型部分验证才能 `record ok`。
|
|
75
75
|
- `仅保留报告` 只停止修复,不构成风险接受或通过。
|
package/enhancements/0.6/.agents/skills/trellis-check-all/references/reporting-and-disposition.md
CHANGED
|
@@ -26,15 +26,10 @@
|
|
|
26
26
|
|
|
27
27
|
### `FBK-*` 兜底问题
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
满足硬准入的兜底根因沿用上方标题行字段与呈现规则;ID 独立从 `FBK-001` 递增,其余字段如下:
|
|
30
30
|
|
|
31
31
|
| 字段 | 呈现 | 规则 |
|
|
32
32
|
| --- | --- | --- |
|
|
33
|
-
| ID | 标题行 | 首次记录时依次分配 `FBK-001`、`FBK-002`;当前修复/重检循环中不重新编号 |
|
|
34
|
-
| 严重度 | 标题行 | 与 `CHK-*` 使用同一 P0/P1/P2 影响尺度 |
|
|
35
|
-
| 来源 | 标题行 | prd/design/implement/spec/assumption/verification |
|
|
36
|
-
| 处置 | 标题行 | 仅 `已接受风险` 时在标题行末尾追加 `` `[已接受风险]` `` 标签;待处理是默认状态,不加标签也不占行 |
|
|
37
|
-
| 标题 | 标题行 | 描述具体保护路径根因,不写泛化“增强健壮性” |
|
|
38
33
|
| 证据 | 加粗字段 | 保护缺失、错误或可绕过的全部受影响 `file:line`,以及实际契约或命令结果;承载硬准入的「具体位置」与「问题证据」,不再单列「位置」 |
|
|
39
34
|
| 兜底场景 | 加粗字段 | 可达的异常、失败、越权、数据损害或诊断盲区场景;承载硬准入的「可达场景」 |
|
|
40
35
|
| 影响 | 加粗字段 | 当前缺口的用户、数据、安全或工程影响 |
|
|
@@ -42,9 +37,9 @@
|
|
|
42
37
|
| 建议 | 加粗字段 | 推荐修复方式,不在检查阶段执行 |
|
|
43
38
|
| 验证 | 加粗字段 | 修复后的测试、故障注入、命令或手动验证步骤;受环境限制时按验证阶段标记阻断型 `部分验证` 或 `[上线后验证]` |
|
|
44
39
|
|
|
45
|
-
`FBK-*`
|
|
40
|
+
`FBK-*` 分类和环境不足处理沿用 fallback reference;保护收益与验证方式仍为报告字段。
|
|
46
41
|
|
|
47
|
-
`CHK-*` 与 `FBK-*` 分开编号,同根因位置合并。严重度排序只在各自通道内部生效,每个通道内部按 `P0 -> P1 -> P2` 展示且不重排 ID。跨通道报告顺序固定为完整 `CHK-*` 区块在前、完整 `FBK-*` 区块在后;禁止因 FBK 严重度更高、分类时先判断 FBK、发现先后或 ID 分配时机而 FBK-first
|
|
42
|
+
`CHK-*` 与 `FBK-*` 分开编号,同根因位置合并。严重度排序只在各自通道内部生效,每个通道内部按 `P0 -> P1 -> P2` 展示且不重排 ID。跨通道报告顺序固定为完整 `CHK-*` 区块在前、完整 `FBK-*` 区块在后;禁止因 FBK 严重度更高、分类时先判断 FBK、发现先后或 ID 分配时机而 FBK-first 或交错。新根因递增编号。处置不改变 ID、通道或严重度。
|
|
48
43
|
|
|
49
44
|
## 风险接受
|
|
50
45
|
|
|
@@ -52,12 +47,20 @@
|
|
|
52
47
|
|
|
53
48
|
1. 只有用户可以接受风险;主会话、subagent 和 validated auto-loop 都不得代替用户推断或授权。
|
|
54
49
|
2. 按当前报告和语义解析:“接受当前报告全部风险”“全部接受”“这些风险都接受”等覆盖全部 `CHK-*` / `FBK-*`,包括 P0,无固定句式或逐项 ID。部分接受须唯一定位子集;报告版本或范围不清时才追问。
|
|
55
|
-
3.
|
|
56
|
-
4.
|
|
50
|
+
3. 接受绑定该问题的证据与相关 diff。代码、契约或验证变化后,先核对是否实质改变该问题的证据、触发条件、影响或严重度;改变时仅该问题的原接受失效,恢复为待处理并说明变化。无关文件改动、行号移动或不改变问题语义的报告整理不使接受失效。无法确认关联证据仍有效时明确缺口,不推断继续有效。
|
|
51
|
+
4. 原报告与接受记录保留完整问题、原通道、严重度和证据;不得删除条目、改列 `DOC-*` 或伪报已修复。对话展示按下方“接受后的增量展示”执行;需要展开已接受条目时,标题行末尾追加 `` `[已接受风险]` `` 标签。
|
|
57
52
|
5. `strict pass` 只用于剩余 `CHK-*` / `FBK-*` 均为 0。所有剩余问题均已被有效接受,且无 blocked、无阻断型部分验证、无未接受的实质剩余风险时,结论为 `通过·已接受风险`。
|
|
58
53
|
6. blocked、阻断型部分验证和无法唯一对应当前报告范围的实质剩余风险不是 `CHK-*` / `FBK-*` 处置状态,不能借风险接受绕过;`[上线后验证]` 不属于风险接受对象。
|
|
59
54
|
7. `仅保留报告` 表示停止处置并等待,不等于接受风险,也不授权写文件;只有带明确接受语义的用户回复才改变问题处置状态。
|
|
60
55
|
|
|
56
|
+
### 接受后的增量展示
|
|
57
|
+
|
|
58
|
+
- 首次报告完整展示全部问题。若只改变处置状态,简短确认本次接受的 ID、更新后的结论和必要的下一步;不重贴报告、维度表、问题字段或原风险说明,也不因此重跑检查。部分接受时补充剩余待处置 ID,不误报通过。
|
|
59
|
+
- 后续重检完整展示新增、实质变化、接受失效及仍待处置的问题;未变化且接受仍有效的问题只汇总数量,计入报告总数与接受数,不重复字段。无须展开的通道省略问题区块。
|
|
60
|
+
- 恢复会话、验证进展和 Update-Spec 内部沿用有效接受记录,不主动复述;Push 按其输出 reference 汇总。用户要求详情时再展开指定问题的原报告与当前处置。
|
|
61
|
+
- 原报告或接受依据无法恢复时,说明缺口并针对受影响项目补核,不凭摘要伪报通过或要求全部重接受。复用现有对话或任务记录,不新增展示次数、状态文件或报告附件。
|
|
62
|
+
- 单纯接受只更新处置;已有当前完成链推进意图时沿用。“接受并继续”等明确表达在通过门禁后同轮进入 Update-Spec,无需再回复“继续”;仍有未处置问题或阻塞时说明剩余项并停止。继续不替代 Push 的精确计划确认。
|
|
63
|
+
|
|
61
64
|
## 验证阶段
|
|
62
65
|
|
|
63
66
|
- `部分验证`:当前结论必需、提交前可完成但证据不足;阻断 strict pass、Update-Spec 和 direct Git。
|
|
@@ -68,16 +71,16 @@
|
|
|
68
71
|
|
|
69
72
|
## 输出:统一检查报告
|
|
70
73
|
|
|
71
|
-
|
|
74
|
+
按“接受后的增量展示”在对话中报告。不得为缩短回复、留存结论或同步任务状态新建 `check-report.md` 等附件或用链接代替应展示内容。
|
|
72
75
|
|
|
73
|
-
|
|
76
|
+
仅用户明确导出或已确认交付约定要求时由主会话保存。Maven、auto-loop 沿用机器证据契约,不额外生成 Markdown;已有报告不自动删除或复制。
|
|
74
77
|
|
|
75
78
|
interactive 完成检查与允许的 DOC 修复后,先自然说明实际改动、行为影响和结论,再展示证据与问题:
|
|
76
79
|
|
|
77
80
|
- 依据当前审查范围的最终 diff 和已读实现,覆盖 staged、unstaged、未跟踪文件及必要的子仓;复用检查时收集的材料,不额外启动 Diff Brief 流程或重复扫描。
|
|
78
81
|
- 按行为说明改前后的差异,只有证据支持时才描述旧行为;无行为变化时说明文档、测试或生成物调整,不罗列文件。
|
|
79
82
|
- 区分已实现、已验证和仍未解决的内容;计划中的功能不得写成已经交付,未归属本次范围的 dirty 不得混入。阻塞或重大问题在开头说明,不能被改动介绍掩盖。
|
|
80
|
-
-
|
|
83
|
+
- 自然段不另设固定字段或空项,按复杂度展开。重检只解释本轮修复及其影响。随后按增量展示规则保留应展开的问题、风险和下一步。
|
|
81
84
|
|
|
82
85
|
```markdown
|
|
83
86
|
## Trellis Check-All 结果
|
|
@@ -116,14 +119,6 @@ interactive 完成检查与允许的 DOC 修复后,先自然说明实际改动
|
|
|
116
119
|
- **建议**:<修复建议>
|
|
117
120
|
- **验证**:<验证命令或步骤>
|
|
118
121
|
|
|
119
|
-
#### `CHK-002` `P2` `<来源>` <标题> `[已接受风险]`
|
|
120
|
-
|
|
121
|
-
- **证据**
|
|
122
|
-
- `<file:line>` — <契约、实际值或命令结果>
|
|
123
|
-
- **影响**:<影响>
|
|
124
|
-
- **建议**:<修复建议>
|
|
125
|
-
- **验证**:<验证命令或步骤>
|
|
126
|
-
|
|
127
122
|
### 兜底问题
|
|
128
123
|
|
|
129
124
|
#### `FBK-001` `P1` `<来源>` <标题>
|
|
@@ -152,20 +147,19 @@ interactive 完成检查与允许的 DOC 修复后,先自然说明实际改动
|
|
|
152
147
|
|
|
153
148
|
展示规则:
|
|
154
149
|
|
|
155
|
-
- strict pass
|
|
150
|
+
- strict pass 或仅剩未变化的有效已接受问题时可紧凑表述,保留模板顺序、画像、维度、实际验证、DOC(如有)、风险和下一步,省略空区块;不得缩减实际检查范围。应展开的问题完整展示字段与处置;仅更新接受状态时使用简短确认,不套用本模板。
|
|
156
151
|
- 报告头部“工作/范围/画像/结论”和“修复批次”必须使用 `- ` 列表项,不得改为裸行或依赖行尾空格。
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
160
|
-
-
|
|
152
|
+
- 展开项使用 `` #### `<ID>` `<严重度>` `<来源>` <标题> ``;仅已接受项追加 `` `[已接受风险]` ``,来源与处置不另占行。
|
|
153
|
+
- 禁止用 `- [ ]` / `- [x]` 承载问题:终端会压平松散列表,四级标题能稳定分隔。修复状态用“修复结果”表格表达。
|
|
154
|
+
- 字段使用 `- **<字段>**:<值>` 加粗列表标签,避免折行后难以定位。
|
|
155
|
+
- 位置并入 `证据`:`- **证据**` 后接子列表,全部受影响 `file:line` 逐项列出,不用 `;` 堆叠或仅写概述。
|
|
161
156
|
- 没有 `DOC-*` 自动修复时省略“自动修复”区。
|
|
162
|
-
-
|
|
163
|
-
-
|
|
157
|
+
- 本轮无须展开的通道省略问题区。
|
|
158
|
+
- 展开顺序遵循上方通道规则,不得按全局严重度排序反转或交错两个区块。
|
|
164
159
|
- 存在未处置 `CHK-*` 或 `FBK-*` 时,“修复批次”只说明分组与验证安排,处置选择统一在报告末尾“下一步”中提供一次,不再逐项提问。
|
|
165
160
|
- `修复全部` 始终覆盖全部 `CHK-*` 与 `FBK-*`;精确修复可以混合两类 ID。
|
|
166
|
-
- 风险接受可混合两类 ID;“接受当前报告全部风险”覆盖全部剩余问题,包括 P0,无固定句式。全部有效接受后才形成“通过·已接受风险”。
|
|
167
161
|
- interactive 标准报告必须以“下一步”段结束;停止等待不等于省略引导。
|
|
168
|
-
- 独立 `CHK-*` 或 `FBK-*`
|
|
162
|
+
- 独立 `CHK-*` 或 `FBK-*` 不得因数量多而静默省略;合并同根因后列全应展开项,已接受项按增量规则汇总。
|
|
169
163
|
- 报告不得包含 commit message、拟提交/暂存文件、commit-only 决策或提交确认。
|
|
170
164
|
- light 通过正式满足 Phase 2.2 检查门禁;未执行维度必须标记 `N/A`,不得伪装为已验证。
|
|
171
165
|
|
|
@@ -198,7 +192,7 @@ interactive 完成检查与允许的 DOC 修复后,先自然说明实际改动
|
|
|
198
192
|
|
|
199
193
|
### 未修复与风险
|
|
200
194
|
|
|
201
|
-
-
|
|
195
|
+
- <待处置、新增或变化的问题及风险;未变化的有效已接受问题只汇总数量;没有时写“无”>
|
|
202
196
|
|
|
203
197
|
结论:<重检结论>
|
|
204
198
|
|
|
@@ -222,7 +216,7 @@ validated auto-loop 复用相同的画像、profile、`DOC-*` 通道和问题模
|
|
|
222
216
|
- 产品决策、越权、提交前生产副作用授权或破坏性决策:`record --result blocked`。
|
|
223
217
|
- 无 `CHK-*` / `FBK-*` 和阻断型部分验证:`record --result ok --effective-check-depth <light|full> --check-depth-reason <summary>`;摘要包含自动修复和全部 `[上线后验证]`,后者不阻断且不得代执行。
|
|
224
218
|
- record 成功后立即 `next`;若返回 `status=retryable reason=artifact-drift`,不得 `next`,先按 runner 指令在同一 outstanding action 内自纠并重录。validated auto-loop 不渲染交互式下一步段、不提示用户回复“继续”、不等待普通修复范围选择。
|
|
225
|
-
-
|
|
219
|
+
- `artifact-recovery-required` 交由 `trellis-auto-loop`;不叠加 Check 重录预算,不改 fix/recheck、commit-only、队列。
|
|
226
220
|
|
|
227
221
|
subagent 只返回结构化 `CHK-*`、`FBK-*`、`DOC-*` 候选、报告和 `check_profile`;主会话收到后必须完成允许的 `DOC-*` 处理,再完成匹配 action 的 `record + next`。
|
|
228
222
|
|
|
@@ -230,12 +224,12 @@ subagent 只返回结构化 `CHK-*`、`FBK-*`、`DOC-*` 候选、报告和 `chec
|
|
|
230
224
|
|
|
231
225
|
## Interactive Post-Check Stop Gate
|
|
232
226
|
|
|
233
|
-
非 validated auto-loop
|
|
227
|
+
非 validated auto-loop 先按本文件输出标准报告或接受状态的简短确认,再依序分流;不重贴已有报告:
|
|
234
228
|
|
|
235
229
|
1. 只从当前完成链证据识别 direct Git intent:触发检查的最新用户消息明确请求普通 push 或用户主动 `commit-only`;或者 Check-All 已因该 Git 请求报告并停止后,用户在当前报告上明确接受风险并要求继续。不得从任务标题、摘要、dirty 状态、无关历史或 auto-loop 内部 action 推断。
|
|
236
|
-
2. direct Git
|
|
230
|
+
2. direct Git 或用户明确要求继续,可在 strict pass,或全部 findings 已有效接受时继续;还须无阻塞、无阻断型部分验证、无未接受且未标记 `[上线后验证]` 的实质风险。允许已验证 `DOC-*` 和完整登记的 `[上线后验证]`;报告或简短确认后同轮进入 Update-Spec,`no-op|written` 再到 Push,`needs-review` 停止。
|
|
237
231
|
3. 未处置 `CHK-*` / `FBK-*`、blocked、阻断型部分验证或其它未接受实质风险时,报告并停止,不运行 Update-Spec 或生成 Git 计划。Git 请求不授权修复或代用户接受风险。
|
|
238
|
-
4. 没有匹配 direct Git intent
|
|
232
|
+
4. 没有匹配 direct Git intent 且用户未要求继续的普通 interactive 检查保持原行为:报告或简短确认后停止并等待用户选择。
|
|
239
233
|
|
|
240
234
|
### 交互式下一步引导
|
|
241
235
|
|
|
@@ -243,11 +237,9 @@ subagent 只返回结构化 `CHK-*`、`FBK-*`、`DOC-*` 候选、报告和 `chec
|
|
|
243
237
|
|
|
244
238
|
1. 有未处置 findings:提示 `修复全部`、精确 ID、接受当前报告全部风险、`接受风险 <ID> 并继续` 或 `仅保留报告`;不逐项重复确认。
|
|
245
239
|
2. 有 blocked、阻断型部分验证或未标记 `[上线后验证]` 的实质风险:指出所需决策、授权或验证,完成后重跑 Check-All;不自行执行生产、外部或破坏性操作。
|
|
246
|
-
3. direct Git strict pass
|
|
247
|
-
4. 无 direct Git intent
|
|
240
|
+
3. direct Git 或用户已要求继续,且 strict pass / 已接受风险通过:说明本轮正在进入 `trellis-update-spec`,不要求用户再次回复“继续”;Git 计划确认仍由 Push 执行。
|
|
241
|
+
4. 无 direct Git intent、用户未要求继续且 strict pass / 已接受风险通过:提示用户回复 `继续`,下一轮进入 `trellis-update-spec`,再由 `trellis-push` 生成提交计划。
|
|
248
242
|
|
|
249
243
|
停止边界只控制是否自动推进,不能让报告在没有下一步提示的情况下结束。
|
|
250
244
|
|
|
251
|
-
标准报告仅包含上方统一模板定义的检查内容和本 Gate 的唯一主动作。
|
|
252
|
-
|
|
253
245
|
Check-All 不新增 direct Git 摘要或 Git 计划;这些仍由 Update-Spec 与 Push 所有。`[上线后验证]` 交给 Push 风险摘要和既有 `trellis-release` / `release.md`。
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
- **顺序**:<repo-a> [-> `<local generation command>`] -> <repo-b> [-> task progress]
|
|
14
14
|
|
|
15
15
|
### 完成链证据
|
|
16
|
-
- **Check-All**:<通过 /
|
|
16
|
+
- **Check-All**:<通过 / 通过(N 项风险已接受) / 未运行 / 已失效 / 存在未处置 findings / blocked / 部分验证>
|
|
17
17
|
- **Update-Spec**:<no-op / written / needs-review / 未运行 / 已失效>
|
|
18
18
|
|
|
19
19
|
### 1. <repository-name>
|
|
@@ -57,7 +57,8 @@
|
|
|
57
57
|
- 计划中的保留变更按仓库计数:不超过 8 项时逐项标注 `[untracked]`、`[unstaged]`、`[staged]`;超过 8 项时将非 staged 项按目录与 Git 状态汇总数量,每仓最多 12 行,必要时合并到上级目录。同一路径计数一次,兼有 staged/unstaged 时同时标注。
|
|
58
58
|
- 计划中的计划外 staged 项始终逐项单列,不计入分组摘要;计划和结果中的真正风险均在独立“风险”区逐项展示,不受行数限制。分组、展开均只改变展示,不改变 exact set 或确认范围。
|
|
59
59
|
- 用户要求“展开保留变更”时在对话中列出同一 exact set 与 Git 状态,不生成清单附件;“展开文件”仍指 planned files。
|
|
60
|
-
- 计划的完成链证据始终显示当前状态,但不重复 Check-All 报告或 Spec review 正文;`未运行`、`已失效`、任一未处置 `CHK-*` / `FBK-*`、blocked、部分验证或 `needs-review`
|
|
60
|
+
- 计划的完成链证据始终显示当前状态,但不重复 Check-All 报告或 Spec review 正文;`未运行`、`已失效`、任一未处置 `CHK-*` / `FBK-*`、blocked、部分验证或 `needs-review` 同时计入风险区。未变化且接受仍有效的问题只在完成链证据中汇总数量,不再进入风险区;内部保留 ID、严重度、影响与接受依据,用户要求详情时再展开。接受失效或无法验证时按实际状态进入风险区并说明变化或证据缺口,不擅自延续接受。`[上线后验证]` 作为非阻断风险逐项保留动作、环境/责任边界和预期结果,不改变 Check-All 状态,并注明由既有 `trellis-release` / `release.md` 流程承接。
|
|
61
|
+
- 顶部“风险 <N>”只统计本次风险区需展开的事项,不包含已经单独汇总的有效已接受问题;不重复计数。同一问题的有效性按 Check-All reporting reference 核对,不因无关 diff 自动失效,也不把展示去重当作已修复或零风险。
|
|
61
62
|
- 无活动 task、untracked 或 `commit-only` 时省略进度动作。
|
|
62
63
|
- 不重复展示检查结果、规范复核、归档或其他阶段的详细信息。
|
|
63
64
|
- 生成前无法确定的内容和增删行写“生成后计算”,不得填预测值。
|
|
@@ -92,6 +93,6 @@
|
|
|
92
93
|
- untracked 结果用“无任务状态”行替代“任务记录”,展示 work id 与 `<已清理/保留待恢复>`;不生成或暗示 task progress commit。没有保留变更、失败或风险时省略对应行或章节。
|
|
93
94
|
- 部分完成时必须明确列出已成功仓库、失败仓库/步骤、当前分支和下一恢复动作。业务结果与 progress sync 状态不得合并成一个模糊结论。
|
|
94
95
|
- 普通成功结果必须确认本任务产生的当前任务目录变更 clean。其它 retained dirty(含计划外 staged)仍逐项核验,已核对保持原状时每仓只报告数量与结论,不重复清单。异常或未核验项列出路径、实际状态和处理情况,不得笼统声称全部保持原状;用户要求详情时再展示实际文件、message、命令或进度,展开文件仍沿用共用规则。
|
|
95
|
-
- Git
|
|
96
|
+
- Git 成功不消除现有风险;成功结果省略未变化且接受仍有效的问题,不重复接受数量或原影响说明。结果的“风险”区保留新增、变化、接受失效或无法验证的事项,以及仍适用的其它完成链风险与 `[上线后验证]`;用户要求详情时再展开原问题与处置。
|
|
96
97
|
- helper 成功但任务记录 commit 失败时,结果写“任务记录 commit 待恢复”,说明本地 `completed` 与 exact task dirty 已保留;任务记录 commit 成功但 push 失败时写“任务记录 push 待恢复”,说明 clean ahead commit 已保留。两种情况都不得暗示需要重复业务提交或 helper 写入。
|
|
97
98
|
- validated auto-loop local completion 不渲染本模板,也不得被普通结果文案描述为任务记录 push 待恢复。
|
|
@@ -75,6 +75,8 @@ helper 只接受当前 session 或唯一 session fallback 的 `.trellis/.runtime
|
|
|
75
75
|
|
|
76
76
|
helper 默认输出为精简 JSON,只包含 route 执行必需的 `status`、`origin`、`mode`、`source`/`reason` 等字段。需要排查完整 `decision`、session 文件、context key、任务路径、个人配置路径或写回标记时,在同一命令末尾加 `--verbose`;不要为了诊断信息额外读取 runtime 文件。
|
|
77
77
|
|
|
78
|
+
auto-loop prepare 使用同一个 `resolve --target <implement|check> --read-only --task <repository-relative-task-path> [--auto-mode <runner-candidate>]` 预检。它仍按匹配任务的 runtime → prefs → runner 临时候选解析,但不写 session、不绑定任务、不扫描其它 run 借用授权;`--task` 只接受项目 `.trellis/tasks/` 内明确存在的非软链任务路径。预检结果不是实际执行决策;执行时仍通过普通 route 恢复并持久化。缺少 helper 或合法模式时 runner 保守要求相应 JSONL context。
|
|
79
|
+
|
|
78
80
|
输出 `status=miss`、文件缺失、JSON 损坏、任务不匹配、source/mode 不合法、prefs 缺失或 prefs 值不合法时,忽略已有状态并继续 Step 2。不要删除不匹配 runtime 文件,避免误伤其他窗口。
|
|
79
81
|
|
|
80
82
|
---
|
|
@@ -463,18 +463,50 @@ def read_runtime(args: argparse.Namespace) -> int:
|
|
|
463
463
|
|
|
464
464
|
|
|
465
465
|
def resolve_route(args: argparse.Namespace) -> int:
|
|
466
|
-
"""
|
|
466
|
+
"""按相同优先级解析执行路由或只读预检,不在预检时切换任务。
|
|
467
|
+
|
|
468
|
+
Args:
|
|
469
|
+
args: 路由目标、只读任务路径和 runner 提供的临时候选模式。
|
|
470
|
+
|
|
471
|
+
Returns:
|
|
472
|
+
JSON 输出的退出码;缺失或非法上下文通过结构化状态表达。
|
|
473
|
+
"""
|
|
467
474
|
repo_root = _repo_root()
|
|
468
475
|
if repo_root is None:
|
|
469
476
|
return _print({"status": "miss", "reason": "not-trellis-project"})
|
|
470
477
|
|
|
478
|
+
read_only = getattr(args, "read_only", False)
|
|
479
|
+
task_ref = getattr(args, "task", None)
|
|
480
|
+
fallback_mode = getattr(args, "auto_mode", None)
|
|
481
|
+
if (task_ref or fallback_mode) and not read_only:
|
|
482
|
+
return _print({"status": "error", "reason": "preview-requires-read-only"})
|
|
483
|
+
if fallback_mode is not None:
|
|
484
|
+
fallback_mode = _normalize_mode(args.target, fallback_mode)
|
|
485
|
+
if fallback_mode is None:
|
|
486
|
+
return _print({"status": "error", "reason": "invalid-auto-route-mode"})
|
|
487
|
+
|
|
471
488
|
current_task, _, context_key, miss = _current_context_or_miss(repo_root)
|
|
472
|
-
if
|
|
489
|
+
if read_only and task_ref:
|
|
490
|
+
# 只接受项目内明确的任务路径,避免预检把任意目录当作任务或跟随软链。
|
|
491
|
+
relative = Path(task_ref)
|
|
492
|
+
task_path = repo_root / relative
|
|
493
|
+
if (
|
|
494
|
+
relative.is_absolute()
|
|
495
|
+
or ".." in relative.parts
|
|
496
|
+
or relative.parts[:2] != (".trellis", "tasks")
|
|
497
|
+
or len(relative.parts) < 3
|
|
498
|
+
or any(path.is_symlink() for path in (task_path, *task_path.parents) if path != repo_root)
|
|
499
|
+
or not (task_path / "task.json").is_file()
|
|
500
|
+
or (task_path / "task.json").is_symlink()
|
|
501
|
+
):
|
|
502
|
+
return _print({"status": "error", "reason": "invalid-task-path"})
|
|
503
|
+
current_task = relative.as_posix()
|
|
504
|
+
elif miss:
|
|
473
505
|
return _print(miss)
|
|
474
|
-
assert current_task is not None
|
|
506
|
+
assert current_task is not None
|
|
475
507
|
|
|
476
|
-
path = _session_path(repo_root, context_key)
|
|
477
|
-
context_result = _read_json_result(path)
|
|
508
|
+
path = _session_path(repo_root, context_key) if context_key else None
|
|
509
|
+
context_result = _read_json_result(path) if path else {"status": "missing", "data": None}
|
|
478
510
|
if context_result["status"] in {"corrupt", "io_error"}:
|
|
479
511
|
return _output(
|
|
480
512
|
args,
|
|
@@ -482,11 +514,12 @@ def resolve_route(args: argparse.Namespace) -> int:
|
|
|
482
514
|
{"path": _rel_path(repo_root, path), "error": context_result.get("error")},
|
|
483
515
|
)
|
|
484
516
|
context = context_result["data"] if isinstance(context_result.get("data"), dict) else {}
|
|
485
|
-
|
|
517
|
+
decisions = context.get("route_decisions")
|
|
518
|
+
decision = decisions.get(args.target) if isinstance(decisions, dict) else None
|
|
486
519
|
normalized = _normalized_decision(decision, args.target, current_task)
|
|
487
520
|
if normalized is not None:
|
|
488
521
|
written_path = path
|
|
489
|
-
if normalized.get("mode") != decision.get("mode"):
|
|
522
|
+
if not read_only and normalized.get("mode") != decision.get("mode"):
|
|
490
523
|
written_path, normalized = _write_runtime_decision(
|
|
491
524
|
repo_root,
|
|
492
525
|
context_key,
|
|
@@ -504,7 +537,7 @@ def resolve_route(args: argparse.Namespace) -> int:
|
|
|
504
537
|
},
|
|
505
538
|
{
|
|
506
539
|
"decision": normalized,
|
|
507
|
-
"path": _rel_path(repo_root, written_path),
|
|
540
|
+
"path": _rel_path(repo_root, written_path) if written_path else None,
|
|
508
541
|
"context_key": context_key,
|
|
509
542
|
"task": current_task,
|
|
510
543
|
"normalized_legacy_mode": normalized.get("mode") != decision.get("mode"),
|
|
@@ -514,14 +547,16 @@ def resolve_route(args: argparse.Namespace) -> int:
|
|
|
514
547
|
prefs = _read_prefs(repo_root)
|
|
515
548
|
pref_mode = prefs.get(args.target)
|
|
516
549
|
if pref_mode in PREF_MODES[args.target]:
|
|
517
|
-
written_path, pref_decision =
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
550
|
+
written_path, pref_decision = path, _decision(args.target, pref_mode, "route-prefs", current_task)
|
|
551
|
+
if not read_only:
|
|
552
|
+
written_path, pref_decision = _write_runtime_decision(
|
|
553
|
+
repo_root,
|
|
554
|
+
context_key,
|
|
555
|
+
current_task,
|
|
556
|
+
args.target,
|
|
557
|
+
pref_mode,
|
|
558
|
+
"route-prefs",
|
|
559
|
+
)
|
|
525
560
|
return _output(
|
|
526
561
|
args,
|
|
527
562
|
{
|
|
@@ -531,29 +566,35 @@ def resolve_route(args: argparse.Namespace) -> int:
|
|
|
531
566
|
},
|
|
532
567
|
{
|
|
533
568
|
"decision": pref_decision,
|
|
534
|
-
"path": _rel_path(repo_root, written_path),
|
|
569
|
+
"path": _rel_path(repo_root, written_path) if written_path else None,
|
|
535
570
|
"pref_path": _rel_path(repo_root, _pref_path(repo_root)),
|
|
536
571
|
"context_key": context_key,
|
|
537
572
|
"task": current_task,
|
|
538
|
-
"wrote_runtime":
|
|
573
|
+
"wrote_runtime": not read_only,
|
|
539
574
|
}
|
|
540
575
|
)
|
|
541
576
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
)
|
|
548
|
-
if auto_mode in PREF_MODES[args.target]:
|
|
549
|
-
written_path, auto_decision = _write_runtime_decision(
|
|
577
|
+
# prepare 尚未进入 running;只读模式只使用 runner 显式传入的候选,
|
|
578
|
+
# 不扫描其它 run 借用授权,也不把预检结果持久化为真实执行决策。
|
|
579
|
+
auto_mode, auto_path, auto_reason = fallback_mode, None, "no-route-authorization"
|
|
580
|
+
if not read_only:
|
|
581
|
+
auto_mode, auto_path, auto_reason = _auto_route_mode(
|
|
550
582
|
repo_root,
|
|
551
583
|
context_key,
|
|
552
584
|
current_task,
|
|
553
585
|
args.target,
|
|
554
|
-
auto_mode,
|
|
555
|
-
"auto-loop",
|
|
556
586
|
)
|
|
587
|
+
if auto_mode in PREF_MODES[args.target]:
|
|
588
|
+
written_path, auto_decision = path, _decision(args.target, auto_mode, "auto-loop", current_task)
|
|
589
|
+
if not read_only:
|
|
590
|
+
written_path, auto_decision = _write_runtime_decision(
|
|
591
|
+
repo_root,
|
|
592
|
+
context_key,
|
|
593
|
+
current_task,
|
|
594
|
+
args.target,
|
|
595
|
+
auto_mode,
|
|
596
|
+
"auto-loop",
|
|
597
|
+
)
|
|
557
598
|
return _output(
|
|
558
599
|
args,
|
|
559
600
|
{
|
|
@@ -563,12 +604,12 @@ def resolve_route(args: argparse.Namespace) -> int:
|
|
|
563
604
|
},
|
|
564
605
|
{
|
|
565
606
|
"decision": auto_decision,
|
|
566
|
-
"path": _rel_path(repo_root, written_path),
|
|
607
|
+
"path": _rel_path(repo_root, written_path) if written_path else None,
|
|
567
608
|
"auto_path": _rel_path(repo_root, auto_path) if auto_path else None,
|
|
568
609
|
"pref_path": _rel_path(repo_root, _pref_path(repo_root)),
|
|
569
610
|
"context_key": context_key,
|
|
570
611
|
"task": current_task,
|
|
571
|
-
"wrote_runtime":
|
|
612
|
+
"wrote_runtime": not read_only,
|
|
572
613
|
}
|
|
573
614
|
)
|
|
574
615
|
|
|
@@ -579,7 +620,7 @@ def resolve_route(args: argparse.Namespace) -> int:
|
|
|
579
620
|
"reason": "no-valid-decision-pref-or-auto",
|
|
580
621
|
},
|
|
581
622
|
{
|
|
582
|
-
"path": _rel_path(repo_root, path),
|
|
623
|
+
"path": _rel_path(repo_root, path) if path else None,
|
|
583
624
|
"pref_path": _rel_path(repo_root, _pref_path(repo_root)),
|
|
584
625
|
"auto_reason": auto_reason,
|
|
585
626
|
"auto_path": _rel_path(repo_root, auto_path) if auto_path else None,
|
|
@@ -753,6 +794,9 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
753
794
|
|
|
754
795
|
resolve_parser = subparsers.add_parser("resolve", help="resolve route from runtime then prefs")
|
|
755
796
|
resolve_parser.add_argument("--target", choices=sorted(VALID_MODES), required=True)
|
|
797
|
+
resolve_parser.add_argument("--read-only", action="store_true", help="preview without writing session state")
|
|
798
|
+
resolve_parser.add_argument("--task", help="explicit repository-relative task path for read-only preview")
|
|
799
|
+
resolve_parser.add_argument("--auto-mode", help="runner candidate used only after runtime and prefs in read-only preview")
|
|
756
800
|
resolve_parser.add_argument("--verbose", action="store_true", help="include diagnostic paths and session metadata")
|
|
757
801
|
resolve_parser.set_defaults(func=resolve_route)
|
|
758
802
|
|
|
@@ -7,6 +7,12 @@ description: "从最新 prd.md、design.md、implement.md 生成、刷新、校
|
|
|
7
7
|
|
|
8
8
|
为当前任务生成或更新 `brief.md`,并把交接摘要展示在对话里。`brief.md` 是从三件套派生的交接视图,不替代 `prd.md`、`design.md`、`implement.md`。
|
|
9
9
|
|
|
10
|
+
## Auto-Loop Action 例外
|
|
11
|
+
|
|
12
|
+
调用来自 auto-loop 时,先通过 `auto_loop.py status` 与 `next` 校验真实 run 和当前 action,不从聊天摘要或 raw runtime JSON 推断授权。只有 schema 2、`profile=commit-only`、run 为 `preparing`,且 `next` 返回本任务的 `refresh_brief` 时,才使用本例外:按下方步骤读取、刷新并完整展示 Brief,然后返回 `trellis-auto-loop` 回写同名 action 并立即 `next`;不等待逐任务人工确认,也不直接执行 `task.py start`。
|
|
13
|
+
|
|
14
|
+
本例外沿用 runner 的 prepare、Open Questions、readiness 和 artifact 校验,不扩张任务或授权边界。schema 1 返回的 `refresh_brief` 同样在展示后交回 runner,由后续 `confirm_brief` action 等待人工确认。run 已停止、终态、损坏或 action/task 不匹配时不得免确认或代为推进;由 auto-loop owner 处理诊断。普通交互调用继续遵守以下确认规则。
|
|
15
|
+
|
|
10
16
|
## 核心规则
|
|
11
17
|
|
|
12
18
|
- 每次运行都重新读取最新 `prd.md`、`design.md if present`、`implement.md if present`。
|
|
@@ -14,9 +20,9 @@ description: "从最新 prd.md、design.md、implement.md 生成、刷新、校
|
|
|
14
20
|
- `brief.md` 必须以三件套为准覆盖旧内容;无法从三件套追溯的旧内容不能保留为事实。
|
|
15
21
|
- 不要在 `brief.md` 里发明三件套没有表达的新需求。必填字段缺失时写“未明确”,并提示应补充三件套;没有相关内容时直接省略 `Risks / Deferred` 整节。
|
|
16
22
|
- 写回 `brief.md` 后,必须在当前对话中展示 brief 正文;不要只给文件路径。
|
|
17
|
-
- Phase 1.4 前必须展示完整 brief
|
|
23
|
+
- Phase 1.4 前必须展示完整 brief。除上方经 runner 校验的 Auto-Loop Action 例外外,默认等待用户确认后再运行 `task.py start`;只有用户明确把当前任务或最终 Brief 与“展示后直接开始 / 不用再次确认 / 视为已确认”绑定时,才可在范围未变化的前提下免除第二次确认。
|
|
18
24
|
- “开始做吧”“按你建议来”“可以创建任务”等普通实现或建任务意图不是 Brief 预授权,不能据此跳过确认。
|
|
19
|
-
-
|
|
25
|
+
- 普通交互预授权只依赖当前对话中仍然明确可见的用户表达,不建立跨会话永久偏好,也不写 session runtime;auto-loop 恢复由上方 runner 例外所有。
|
|
20
26
|
- `in_progress` 阶段只读取 brief 和任务材料,不例行重新生成、展示或确认;新会话或压缩恢复同样如此。范围变化沿用 workflow 的既有评审门禁,用户明确要求查看时再完整展示。
|
|
21
27
|
- `in_progress` 阶段发现缺失 brief 时,不自动生成未经 review 的 brief;先读取三件套并建议回补。只有用户明确要求当场回补并 review 时,才继续写回 `brief.md`。
|
|
22
28
|
- 不要机械限制 brief 或对话展示长度;信息完整优先,不能截掉会影响实现判断的范围、约束、风险或验收条件。
|
|
@@ -33,6 +39,7 @@ description: "从最新 prd.md、design.md、implement.md 生成、刷新、校
|
|
|
33
39
|
- 必读:`prd.md`。
|
|
34
40
|
- 存在则读:`design.md`、`implement.md`。
|
|
35
41
|
4. 判断当前对话是否存在有效预授权:
|
|
42
|
+
- 若命中上方 Auto-Loop Action 例外,按 runner 授权处理;以下条件只约束普通交互预授权。
|
|
36
43
|
- 必须由用户明确指向当前任务或最终 Brief,并明确表示展示后直接开始、不用再次确认或视为已确认。
|
|
37
44
|
- 普通实现意图、任务创建授权、旧任务确认或无法确定指向的表达均按“无预授权”处理。
|
|
38
45
|
- 若最终内容扩大范围、仍有未解决 Open Questions,或新增权限、安全、隐私、生产、费用、真实数据、破坏性公开契约、外部系统边界,则预授权失效。
|
|
@@ -47,6 +54,7 @@ description: "从最新 prd.md、design.md、implement.md 生成、刷新、校
|
|
|
47
54
|
- `Next Step`:只写进入下一阶段后的一个直接动作,不展开完整实施计划。
|
|
48
55
|
6. 写回 `<task>/brief.md`。如果文件已存在,仍用最新三件套派生内容覆盖旧正文。
|
|
49
56
|
7. 在对话中展示 brief 正文,并说明来源文件:
|
|
57
|
+
- 经校验的 auto-loop `refresh_brief`:展示后返回 runner,不进入下方交互分支;schema 1 的确认由后续 action 所有。
|
|
50
58
|
- 无有效预授权:展示后结束当前回合,等待用户确认。
|
|
51
59
|
- 有有效预授权:先完整展示,再在同一回合返回主 workflow 执行 `task.py start`,不得省略展示步骤。
|
|
52
60
|
|