flower-trellis 0.3.1 → 0.4.0-beta.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.
@@ -13,9 +13,9 @@ description: |
13
13
 
14
14
  # Trellis 路由器:implement / check 执行模式选择
15
15
 
16
- 主 agent 进入 Phase 2.1 实现路由或 Phase 2.2 检查路由时调用本 skill。当前上下文或 session runtime state 内已有合法来源的最近 route 决策时,后续实现、修复、重检默认复用该决策;没有合法决策时才进入本 skill 或同编号 fallback。提交前确实需要最终复查时,回到 Phase 2.2 并复用当前任务的合法 check route,除非用户明确要求重选。
16
+ 主 agent 进入 Phase 2.1 实现路由或 Phase 2.2 检查路由时调用本 skill。当前上下文或 session runtime state 内已有合法来源、target 匹配、且 task 等于当前任务路径的最近 route 决策时,后续实现、修复、重检默认复用该决策;没有合法决策时才进入本 skill 或同编号 fallback。提交前确实需要最终复查时,回到 Phase 2.2 并复用当前任务的合法 check route,除非用户明确要求重选。
17
17
 
18
- 个人配置只写入 `.trellis/.route-prefs.tmp`。该文件匹配 `.trellis/.gitignore` 的 `*.tmp` 规则,属于开发者本地偏好,不纳入 git,也不影响其他开发者。
18
+ 个人配置只写入 `.trellis/.route-prefs.tmp`。该文件匹配 `.trellis/.gitignore` 的 `*.tmp` 规则,属于开发者本地偏好,不纳入 git,也不影响其他开发者。auto-loop 可在 `.trellis/.runtime/auto-loop/<run-id>.json` 写入临时 route 授权;它不是个人偏好,优先级低于 `.route-prefs.tmp`,只用于减少 auto 模式下的交互打断。
19
19
 
20
20
  本轮 route 决策写入当前 session runtime 文件 `.trellis/.runtime/sessions/<context-key>.json` 的 `route_decisions` 字段。该文件匹配 `.trellis/.gitignore` 的 `.runtime/` 规则,只保存当前 AI session/window 的执行状态,用于压缩后恢复;它不是任务属性,不写入 `.trellis/tasks/**`,也不是长期团队配置。
21
21
 
@@ -25,9 +25,9 @@ description: |
25
25
 
26
26
  个人 route 配置只决定“已获准执行后的模式”,不是开工授权。调用 helper 前,必须确认当前 workflow 已允许进入对应 target:implement 需要任务已完成规划确认并处于 `in_progress`;check 用于 Phase 2.2 检查执行,或用户明确要求最终复查 / 轻量检查。最终复查只有在 Phase 2.2 结果缺失、风险较高或用户明确要求复查时才回到 Phase 2.2;回到 Phase 2.2 后优先复用当前任务的合法 check route,除非用户明确要求重选/临时改/清除默认。如果仍在 planning、等待用户确认,或用户表达“等一下 / 我再想想”,停止,不读取 runtime/prefs。
27
27
 
28
- 合法 route 决策必须能追溯到 `trellis-route`、同编号 fallback 选项,或由本 skill 读取到的有效 `.trellis/.route-prefs.tmp` 配置。runtime state 只能保存和恢复这些原始合法来源,不能把 `.runtime` 自身当成新的 `route_decision.source`。用户自然语言说过“inline/subagent”、compact summary、SessionStart 摘要、`codex-mode`、空 `.route-prefs.tmp`、旧单值偏好,都不能单独作为有效 route 决策。
28
+ 合法 route 决策必须能追溯到 `trellis-route`、同编号 fallback 选项、由本 skill 读取到的有效 `.trellis/.route-prefs.tmp` 配置,或由 route helper 校验过的 auto-loop 临时 route 授权,并且 `task` 字段必须等于当前 `task.py current --source` 返回的任务路径。runtime state 只能保存和恢复这些原始合法来源,不能把 `.runtime` 自身当成新的 `route_decision.source`。用户自然语言说过“inline/subagent”、compact summary、SessionStart 摘要、`codex-mode`、空 `.route-prefs.tmp`、旧单值偏好,都不能单独作为有效 route 决策。
29
29
 
30
- 当前上下文内已有 target 匹配且来源合法的 route 决策时,后续实现、check 发现问题、用户指出刚检查过的实现有问题、修复后重检、提交前复查均默认复用最近 implement/check 路由;除非用户明确要求重选/临时改/清除默认,不再调用本 skill。当前上下文没有 route 决策但 runtime state 命中时,本 skill 恢复该决策并输出同样的结构化 `route_decision`。
30
+ 当前上下文内已有 target 匹配、task 等于当前任务路径、且来源合法的 route 决策时,后续实现、check 发现问题、用户指出刚检查过的实现有问题、修复后重检、提交前复查均默认复用最近 implement/check 路由;除非用户明确要求重选/临时改/清除默认,不再调用本 skill。当前上下文没有 route 决策但 runtime state 命中时,本 skill 恢复该决策并输出同样的结构化 `route_decision`。如果上下文里只有上一个任务的 `route_decision`,必须忽略并重新解析当前任务。
31
31
 
32
32
  Codex inline mode 只表示主会话默认直接执行,不是 route 选项过滤器。即使当前上下文出现 `<codex-mode>inline...do not dispatch...</codex-mode>` 或 `workflow-state:in_progress-inline`,也不能推断“只能 inline”或跳过 subagent 选项;仍必须通过 helper resolve runtime/prefs,或在无有效配置时展示正常 inline/subagent 选项。若本 skill 的紧邻路由决定是 subagent,本步骤允许主 agent dispatch 对应 implement/check sub-agent;禁止的是绕过 `trellis-route` 直接 dispatch。
33
33
 
@@ -50,7 +50,7 @@ Codex inline mode 只表示主会话默认直接执行,不是 route 选项过
50
50
 
51
51
  ## Step 0.5: 解析已有 route state
52
52
 
53
- 仅在没有覆盖意图、当前上下文没有 target 匹配的合法 `route_decision` 时调用 helper 解析已有状态。helper 的解析顺序固定为:当前 session runtime 文件里的 `route_decisions` → `.trellis/.route-prefs.tmp`。命中 `.route-prefs.tmp` 时,helper 会自动把 `source=route-prefs` 的决策写回当前 session runtime,后续压缩恢复不需要再次读 prefs
53
+ 仅在没有覆盖意图、当前上下文没有 target + 当前 task 匹配的合法 `route_decision` 时调用 helper 解析已有状态。helper 的解析顺序固定为:当前 session runtime 文件里的 `route_decisions` → `.trellis/.route-prefs.tmp` `.trellis/.runtime/auto-loop/<run-id>.json` 临时授权。命中 `.route-prefs.tmp` auto-loop 临时授权时,helper 会自动把对应决策写回当前 session runtime,后续压缩恢复不需要再次读 prefs 或 auto-loop 状态。
54
54
 
55
55
  调用随本 skill 分发的 helper;不要在对话中内嵌或改写 helper 逻辑:
56
56
 
@@ -60,7 +60,7 @@ python3 .agents/skills/trellis-route/scripts/route_state.py resolve --target <im
60
60
  python3 .claude/skills/trellis-route/scripts/route_state.py resolve --target <implement|check>
61
61
  ```
62
62
 
63
- helper 只接受当前 session 或唯一 session fallback 的 `.trellis/.runtime/sessions/<context-key>.json`,并只从 `route_decisions.<target>` 恢复决策。命中时输出 `{"status":"hit", ...}`,其中默认输出里的 `mode` / `source` 已经过 task/target/source/mode/scope 校验,可跳过 Step 2 并进入 Step 3 输出决策。`origin=route-prefs` 表示来自个人 route 配置,并且 helper 已写回 session runtime state;`origin=runtime` 表示来自 session runtime state。
63
+ helper 只接受当前 session 或唯一 session fallback 的 `.trellis/.runtime/sessions/<context-key>.json`,并只从 `route_decisions.<target>` 恢复当前任务的决策。命中时输出 `{"status":"hit", ...}`,其中默认输出里的 `task` / `mode` / `source` 已经过 task/target/source/mode/scope 校验,可跳过 Step 2 并进入 Step 3 输出决策。`origin=route-prefs` 表示来自个人 route 配置,并且 helper 已写回 session runtime state;`origin=auto-loop` 表示来自 auto-loop 临时授权且 helper 已写回 session runtime state;`origin=runtime` 表示来自 session runtime state。
64
64
 
65
65
  helper 默认输出为精简 JSON,只包含 route 执行必需的 `status`、`origin`、`mode`、`source`/`reason` 等字段。需要排查完整 `decision`、session 文件、context key、任务路径、个人配置路径或写回标记时,在同一命令末尾加 `--verbose`;不要为了诊断信息额外读取 runtime 文件。
66
66
 
@@ -181,7 +181,9 @@ python3 .agents/skills/trellis-route/scripts/route_state.py clear-pref --target
181
181
  python3 .claude/skills/trellis-route/scripts/route_state.py clear-pref --target <implement|check>
182
182
  ```
183
183
 
184
- helper 写入规则:保留另一个 target 的 runtime 决策和偏好;覆盖当前 target;`source` 保持原始合法来源,正常 skill 交互用 `trellis-route`,普通聊天编号 fallback 用 `numbered-fallback`,prefs 命中由 helper 写 `route-prefs`;保留 session runtime 文件中的 `platform`、`current_task`、`current_run` 等既有字段;内部 `task` 必须写当前 `task.py current --source` 的任务路径。写入失败不阻塞本次 route 输出,但要在回复中简短说明未持久化,压缩后可能再次询问。
184
+ helper 写入规则:保留另一个 target 的 runtime 决策和偏好;覆盖当前 target;`source` 保持原始合法来源,正常 skill 交互用 `trellis-route`,普通聊天编号 fallback 用 `numbered-fallback`,prefs 命中由 helper 写 `route-prefs`,auto-loop 临时授权命中由 helper 写 `auto-loop`;保留 session runtime 文件中的 `platform`、`current_task`、`current_run`、`current_auto_run` 等既有字段;内部 `task` 必须写当前 `task.py current --source` 的任务路径。写入失败不阻塞本次 route 输出,但要在回复中简短说明未持久化,压缩后可能再次询问。
185
+
186
+ 当同一 session 从一个任务切换到另一个任务时,helper 写入当前任务任一 target 的决策前会清理 runtime 中属于其他任务的 `route_decisions`。个人默认仍保留在 `.trellis/.route-prefs.tmp`;清理只影响当前 session 的临时恢复状态,目的是避免新任务的 check 阶段误复用上一个任务的 check 路由。
185
187
 
186
188
  ---
187
189
 
@@ -205,6 +207,7 @@ helper 写入规则:保留另一个 target 的 runtime 决策和偏好;覆
205
207
  ```markdown
206
208
  路由决定:<inline/subagent> <implement | check-all | check>
207
209
  [来自个人 route 配置:`.trellis/.route-prefs.tmp` (<key>=<value>)。]
210
+ [来自 auto-loop 临时 route 授权:`.trellis/.runtime/auto-loop/<run-id>.json`。]
208
211
  [来自 session runtime route state:`.trellis/.runtime/sessions/<context-key>.json` 的 `route_decisions`。]
209
212
  [已写入 session runtime route state:`.trellis/.runtime/sessions/<context-key>.json` 的 `route_decisions`。]
210
213
  [说明:用户明确请求轻量检查,使用隐藏逃生口。]
@@ -212,8 +215,9 @@ helper 写入规则:保留另一个 target 的 runtime 决策和偏好;覆
212
215
  route_decision:
213
216
  target: <implement | check>
214
217
  mode: <inline | subagent | check-all-inline | check-all-subagent | check-inline | check-subagent>
215
- source: <trellis-route | route-prefs | numbered-fallback>
218
+ source: <trellis-route | route-prefs | auto-loop | numbered-fallback>
216
219
  scope: task
220
+ task: <current task path>
217
221
 
218
222
  接下来主 agent 应当:
219
223
  - <路由表里对应的工具调用形式>
@@ -223,7 +227,7 @@ route_decision:
223
227
  - <要避免的工具调用>
224
228
  ```
225
229
 
226
- 中括号内行为条件性出现:仅命中个人配置时显示配置行;仅命中 runtime state 时显示“来自”行;写入 runtime state 成功时显示“已写入”行;仅轻量 check 时显示隐藏逃生口说明;仅 implement subagent + skip_compile=true 时附加“跳过编译”段。`route_decision` 必须保留在回复中,但默认只保留 target/mode/source/scope;需要 task/path/decided_at 等诊断字段时重新调用 helper 并加 `--verbose`。compact summary 若只有自然语言描述,后续 agent 仍应优先读取 runtime state,而不是把 summary 当证据。
230
+ 中括号内行为条件性出现:仅命中个人配置时显示配置行;仅命中 runtime state 时显示“来自”行;写入 runtime state 成功时显示“已写入”行;仅轻量 check 时显示隐藏逃生口说明;仅 implement subagent + skip_compile=true 时附加“跳过编译”段。`route_decision` 必须保留在回复中,并至少保留 target/mode/source/scope/task;需要 path/decided_at 等诊断字段时重新调用 helper 并加 `--verbose`。compact summary 若只有自然语言描述,后续 agent 仍应优先读取 runtime state,而不是把 summary 当证据。
227
231
 
228
232
  ---
229
233
 
@@ -233,13 +237,14 @@ route_decision:
233
237
  2. **runtime state 私有**:`.trellis/.runtime/sessions/` 是 session/window 状态,gitignored,不能进入提交计划。
234
238
  3. **压缩恢复少打断**:当前上下文没有 route 决策时,先读 runtime state;命中当前任务/target 的合法决策就复用,不查 `trellis mem`,也不重问。
235
239
  4. **个人默认次于本轮决策**:runtime state 表示“本轮已选”,优先于 `.route-prefs.tmp`。
236
- 5. **显式覆盖优先于一切**:用户要求临时改、重新选择或清除默认时,必须重新展示选项,不能让 runtime state 或配置优先。
237
- 6. **当前任务复用路由**:当前任务内已有合法来源的最近 implement/check 路由时,后续实现、修复、重检和复查默认沿用,不再次询问模式。
238
- 7. **check 默认全面检查**:普通 check 路由只展示 `check-all` inline/subagent,不推荐轻量 `trellis-check`。
239
- 8. **轻量 check 是隐藏逃生口**:只有用户明确请求 `light check` / `轻量检查` 时才可走轻量 `trellis-check`。
240
- 9. **决策与执行分离**:本 skill 只输出指令,下一轮由主 agent 调工具。
241
- 10. **严格执行用户选择**:路由结论一旦输出,主 agent 必须按指令执行,不可“出于谨慎”再换路径。
242
- 11. **Codex inline 不裁剪选项**:Codex inline 是默认执行模式,不是只能 inline 的强制模式;route 明确选中 subagent 时,本步骤可按 subagent 路径执行。
240
+ 5. **auto 授权低于个人默认**:auto-loop 临时授权只在 runtime 和个人偏好都 miss 时生效。
241
+ 6. **显式覆盖优先于一切**:用户要求临时改、重新选择或清除默认时,必须重新展示选项,不能让 runtime state 或配置优先。
242
+ 7. **当前任务复用路由**:当前任务内已有合法来源的最近 implement/check 路由时,后续实现、修复、重检和复查默认沿用,不再次询问模式。
243
+ 8. **check 默认全面检查**:普通 check 路由只展示 `check-all` inline/subagent,不推荐轻量 `trellis-check`。
244
+ 9. **轻量 check 是隐藏逃生口**:只有用户明确请求 `light check` / `轻量检查` 时才可走轻量 `trellis-check`。
245
+ 10. **决策与执行分离**:本 skill 只输出指令,下一轮由主 agent 调工具。
246
+ 11. **严格执行用户选择**:路由结论一旦输出,主 agent 必须按指令执行,不可“出于谨慎”再换路径。
247
+ 12. **Codex inline 不裁剪选项**:Codex inline 是默认执行模式,不是只能 inline 的强制模式;route 明确选中 subagent 时,本步骤可按 subagent 路径执行。
243
248
 
244
249
  ---
245
250
 
@@ -12,7 +12,7 @@ from pathlib import Path
12
12
  from typing import Any
13
13
 
14
14
 
15
- VALID_SOURCES = {"trellis-route", "numbered-fallback", "route-prefs"}
15
+ VALID_SOURCES = {"trellis-route", "numbered-fallback", "route-prefs", "auto-loop"}
16
16
  VALID_MODES = {
17
17
  "implement": {"inline", "subagent"},
18
18
  "check": {
@@ -83,6 +83,7 @@ def _output(args: argparse.Namespace, data: dict[str, Any], verbose: dict[str, A
83
83
  def _decision_summary(decision: dict[str, Any]) -> dict[str, Any]:
84
84
  """提取默认输出需要的最小 route 决策字段。"""
85
85
  return {
86
+ "task": decision.get("task"),
86
87
  "mode": decision.get("mode"),
87
88
  "source": decision.get("source"),
88
89
  }
@@ -129,6 +130,16 @@ def _pref_path(repo_root: Path) -> Path:
129
130
  return repo_root / ".trellis/.route-prefs.tmp"
130
131
 
131
132
 
133
+ def _auto_loop_dir(repo_root: Path) -> Path:
134
+ """返回 auto-loop runtime 目录。"""
135
+ return repo_root / ".trellis/.runtime/auto-loop"
136
+
137
+
138
+ def _auto_loop_pointer(repo_root: Path) -> Path:
139
+ """返回当前 auto-loop run 指针文件。"""
140
+ return _auto_loop_dir(repo_root) / "current.json"
141
+
142
+
132
143
  def _read_prefs(repo_root: Path) -> dict[str, str]:
133
144
  """读取个人 route 默认配置,只保留合法 key-value。"""
134
145
  path = _pref_path(repo_root)
@@ -149,6 +160,47 @@ def _read_prefs(repo_root: Path) -> dict[str, str]:
149
160
  return prefs
150
161
 
151
162
 
163
+ def _auto_route_mode(repo_root: Path, context_key: str, target: str) -> tuple[str | None, Path | None, str | None]:
164
+ """读取当前 auto-loop run 的临时 route 授权。
165
+
166
+ auto 授权低于个人 `.route-prefs.tmp`,只在当前 session runtime 绑定了
167
+ `current_auto_run`,或全局 current 指针能指向唯一 running run 时生效。命中后
168
+ `resolve` 会写回 session runtime,后续压缩恢复仍走普通 route 决策路径。
169
+ """
170
+ session_path = _session_path(repo_root, context_key)
171
+ session = _read_json(session_path)
172
+ run_id = session.get("current_auto_run")
173
+
174
+ if not isinstance(run_id, str) or not run_id.strip():
175
+ pointer = _read_json(_auto_loop_pointer(repo_root))
176
+ run_id = pointer.get("run_id")
177
+
178
+ candidate_paths: list[Path] = []
179
+ if isinstance(run_id, str) and run_id.strip():
180
+ candidate_paths.append(_auto_loop_dir(repo_root) / f"{run_id.strip()}.json")
181
+ else:
182
+ for path in sorted(_auto_loop_dir(repo_root).glob("auto-*.json")):
183
+ state = _read_json(path)
184
+ if state.get("status") == "running":
185
+ candidate_paths.append(path)
186
+ if len(candidate_paths) != 1:
187
+ return None, None, "no-unique-auto-run"
188
+
189
+ path = candidate_paths[0]
190
+ state = _read_json(path)
191
+ if state.get("status") != "running":
192
+ return None, path, "auto-run-not-running"
193
+
194
+ auth = state.get("route_authorization")
195
+ if not isinstance(auth, dict):
196
+ return None, path, "no-route-authorization"
197
+
198
+ mode = auth.get(target)
199
+ if mode in PREF_MODES[target]:
200
+ return mode, path, None
201
+ return None, path, "invalid-auto-route-mode"
202
+
203
+
152
204
  def _write_prefs(repo_root: Path, prefs: dict[str, str]) -> None:
153
205
  """写入个人 route 默认配置;为空则删除文件。"""
154
206
  path = _pref_path(repo_root)
@@ -218,6 +270,13 @@ def _write_runtime_decision(
218
270
  decisions = context.get("route_decisions")
219
271
  if not isinstance(decisions, dict):
220
272
  decisions = {}
273
+ # 同一 AI session 可能连续处理多个 Trellis 任务。写入新任务的任一路由时,
274
+ # 先丢弃旧任务的 runtime 决策,避免后续 check 阶段绕过 helper 时误复用上个任务的选择。
275
+ decisions = {
276
+ key: value
277
+ for key, value in decisions.items()
278
+ if isinstance(value, dict) and value.get("task") == current_task
279
+ }
221
280
  decision = _decision(target, mode, source, current_task)
222
281
  decision["decided_at"] = now
223
282
  decisions[target] = decision
@@ -280,7 +339,7 @@ def read_runtime(args: argparse.Namespace) -> int:
280
339
 
281
340
 
282
341
  def resolve_route(args: argparse.Namespace) -> int:
283
- """按 runtime → prefs 的优先级解析 route 决策。"""
342
+ """按 runtime → prefs → auto-loop 的优先级解析 route 决策。"""
284
343
  repo_root = _repo_root()
285
344
  if repo_root is None:
286
345
  return _print({"status": "miss", "reason": "not-trellis-project"})
@@ -337,15 +396,45 @@ def resolve_route(args: argparse.Namespace) -> int:
337
396
  }
338
397
  )
339
398
 
399
+ auto_mode, auto_path, auto_reason = _auto_route_mode(repo_root, context_key, args.target)
400
+ if auto_mode in PREF_MODES[args.target]:
401
+ written_path, auto_decision = _write_runtime_decision(
402
+ repo_root,
403
+ context_key,
404
+ current_task,
405
+ args.target,
406
+ auto_mode,
407
+ "auto-loop",
408
+ )
409
+ return _output(
410
+ args,
411
+ {
412
+ "status": "hit",
413
+ "origin": "auto-loop",
414
+ **_decision_summary(auto_decision),
415
+ },
416
+ {
417
+ "decision": auto_decision,
418
+ "path": _rel_path(repo_root, written_path),
419
+ "auto_path": _rel_path(repo_root, auto_path) if auto_path else None,
420
+ "pref_path": _rel_path(repo_root, _pref_path(repo_root)),
421
+ "context_key": context_key,
422
+ "task": current_task,
423
+ "wrote_runtime": True,
424
+ }
425
+ )
426
+
340
427
  return _output(
341
428
  args,
342
429
  {
343
430
  "status": "miss",
344
- "reason": "no-valid-decision-or-pref",
431
+ "reason": "no-valid-decision-pref-or-auto",
345
432
  },
346
433
  {
347
434
  "path": _rel_path(repo_root, path),
348
435
  "pref_path": _rel_path(repo_root, _pref_path(repo_root)),
436
+ "auto_reason": auto_reason,
437
+ "auto_path": _rel_path(repo_root, auto_path) if auto_path else None,
349
438
  "context_key": context_key,
350
439
  "task": current_task,
351
440
  }
@@ -2,6 +2,7 @@
2
2
  HIGHEST PRIORITY SKILL-GARDEN STATE GUARD (planning-inline):
3
3
  Planning is not implementation permission.
4
4
  Complete prd.md + required context first.
5
+ If the active workflow later routes to sub-agent execution, required context includes real curated entries in both `implement.jsonl` and `check.jsonl`; the seed `_example` row alone is not ready.
5
6
  Before `task.py start`, use `trellis-task-brief` to refresh `brief.md` from the latest task artifacts and display it in chat for review.
6
7
  After status becomes in_progress, next action = `trellis-route(implement)`, not direct edits.
7
8
  <!-- END skill-garden workflow-state planning_inline v0.6 -->
@@ -2,6 +2,7 @@
2
2
  HIGHEST PRIORITY SKILL-GARDEN STATE GUARD (planning):
3
3
  Planning is not implementation permission.
4
4
  Complete prd.md + required context first.
5
+ For sub-agent-dispatch platforms, required context includes real curated entries in both `implement.jsonl` and `check.jsonl`; the seed `_example` row alone is not ready.
5
6
  Before `task.py start`, use `trellis-task-brief` to refresh `brief.md` from the latest task artifacts and display it in chat for review.
6
7
  After status becomes in_progress, next action = `trellis-route(implement)`, not direct edits.
7
8
  <!-- END skill-garden workflow-state planning v0.6 -->
@@ -6,7 +6,7 @@
6
6
 
7
7
  **Priority**: This hub overrides any conflicting Trellis workflow, skill, or command text for the scoped behaviors below.
8
8
 
9
- **Scope**: Phase 1.4 task brief handoff, Phase 2.1 implement routing, Phase 2.2 check/check-all routing, current-task route reuse, post-check stop, Phase 3.4 trellis-push, explicit Phase 3.5 finish-work bookkeeping, and push-progress recovery. State blocks should keep one short skill-garden sentinel; long-form rules live here.
9
+ **Scope**: Phase 1.4 task brief handoff, Phase 2.1 implement routing, Phase 2.2 check/check-all routing, current-task route reuse, post-check stop, auto-loop commit-only preauthorization, Phase 3.4 trellis-push, explicit Phase 3.5 finish-work bookkeeping, and push-progress recovery. State blocks should keep one short skill-garden sentinel; long-form rules live here.
10
10
 
11
11
  **Mechanical rule**: use this hub as the source of truth. Do not add separate top-level skill-garden override sections or multiple skill-garden sentinels inside the same `workflow-state:*` block.
12
12
 
@@ -41,6 +41,8 @@ After `trellis-check` or `trellis-check-all` finishes, stop and report the resul
41
41
 
42
42
  If checks pass, the next allowed workflow steps are Phase 3.3 `trellis-update-spec` and Phase 3.4 `trellis-push`/commit confirmation. `/trellis:finish-work` is explicit-only: run it only after Phase 3.4 is complete and the user asks to wrap up, archive, or finish the task.
43
43
 
44
+ During a running `trellis-auto-loop`, the runner's `record` + `next` replaces the post-check stop gate: after a check pass, record the result, then continue to spec update / commit-only according to `.trellis/scripts/auto_loop.py`. Outside auto-loop, keep the normal stop gate.
45
+
44
46
  #### Code Commit Confirmation Gate
45
47
 
46
48
  Code commit/push belongs only to Phase 3.4 and must go through `trellis-push`; the main session must not run bare `git commit` / `git push` for code.
@@ -49,6 +51,12 @@ Code commit/push belongs only to Phase 3.4 and must go through `trellis-push`; t
49
51
 
50
52
  For "commit now, push later", use `trellis-push` commit-only mode; the later push still goes through `trellis-push`. `session_auto_commit` never authorizes code commits; it only affects bookkeeping commits below.
51
53
 
54
+ #### Auto-loop Commit-only Preauthorization
55
+
56
+ When the user explicitly starts `trellis-auto-loop` with `profile=commit-only`, that start preauthorizes only task-related local commits inside that run. When `.trellis/scripts/auto_loop.py status` reports `run_status=running`, `profile=commit-only`, and `outstanding_action.action=commit_only` for the active task, `trellis-push` may execute commit-only without an additional chat confirmation if the plan contains only files attributable to the current task, performs no push/merge/release/archive, and records the commit hash back to the runner.
57
+
58
+ This exception does not apply to ordinary `trellis-push`. If the plan contains unrecognized staged files, conflicts, dirty files that cannot be attributed safely, push/merge/release/archive intent, external systems, credentials, or production data effects, stop or mark the current auto-loop task blocked.
59
+
52
60
  #### Bookkeeping Auto-commit Scope
53
61
 
54
62
  `session_auto_commit` only governs the bookkeeping commits `task.py archive` / `add_session.py` make for their own `.trellis/tasks/**` and `.trellis/workspace/**` files — never code (gated above). When `false`, those archive/journal writes stay disk-only (no compensating `git commit`).