Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions TaskFlowDocs/2026-09-23-orphan-task-dirs/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Plan — Detect a task directory that no Todo entry references

> Task version: v1
> Status: in_progress

No spec required — small, self-contained task.

## Reference Pointers

- `hooks/repository-check` — uncommitted artifact loop (~69–90); add orphan
pass beside it.
- `hooks/smoke-test` — `== repository-check … ==` sections (~1078+).
- `TaskFlowDocs/todo.md` — `- Task:` backticked paths.
- Predecessor: `TF-20260916-ab381b` (isolation + uncommitted report).

## Related Tasks

- `TF-20260916-a357ee` — this task’s ID.
- `TF-20260916-ab381b` — done; different direction (misplaced/uncommitted).

## Skills / Tools Used

- `Unaided — no capability applied to this phase; considered: shell text
processing and the repository's own check conventions, all read directly.`

## Preconditions

- [x] Docs/rules inspected; worktree `.worktrees/feat-orphan-task-dirs` on
`feat/orphan-task-dirs` from `main` = `5eba691`.
- [x] Incident, direction, and ab381b boundary recorded in PRD Background.

## Approval

- Status: approved
- Approved by: user
- Approved at: 2026-09-23
- Approved version: v1
- Approved scope: PRD / Plan

## Steps

### Step 1 — repository-check orphan report

- Goal: R1–R5.
- Files: `hooks/repository-check`.
- Checklist:
- [x] Collect `- Task:` backticked paths from `todo.md`.
- [x] Scan `TaskFlowDocs/*/` and `TaskFlowDocs/achieved/*/` with prd or
plan; report dirs not referenced (trailing-slash tolerant).
- [x] Orphans set `needs=1`; uncommitted artifacts unchanged.
- [x] `bash -n hooks/repository-check`.
- Acceptance: A, B, C.
- Status: done

### Step 2 — smoke

- Goal: R6/R7.
- Files: `hooks/smoke-test`.
- Checklist:
- [x] Unreferenced active + achieved → listed, exit 2.
- [x] After adding matching `Task:` → not listed.
- [x] Existing repository-check sections still green.
- Acceptance: D, E.
- Status: done

## Checkpoints

- After Step 1: `bash -n` + A/B/C fixtures.
- After Step 2: one full suite; no chained mutations; pkill if killed.

## Verification / Review

| Check | Result |
|---|---|
| `bash -n hooks/repository-check` | pass |
| `bash -n hooks/smoke-test` | pass |
| `bash hooks/smoke-test` | `ALL SMOKE PASSED` |
| `git diff --check` | clean |
| Active orphan listed / ref clears (A/B) | pass (suite) |
| Achieved orphan (C) | pass (suite) |
| Existing check sections (D) | pass (suite) |

## Change Log

- v1 — planning; Q1 orphan sets needs, Q2 no reverse hard-fail, Q3 no
special-case names.
- v1 — approved (user, 2026-09-23); Steps 1–2 done; suite green.

## Follow-ups

- Housekeeping commit `5eba691` is on local main only until next push.
- If live tree reports the known historical achieved orphan after merge:
human decides tombstone vs extra Todo line (data, not code).

## Version History

- v1 — planning.
- v1 — approved (user, 2026-09-23); Steps 1–2 done; suite green.
127 changes: 127 additions & 0 deletions TaskFlowDocs/2026-09-23-orphan-task-dirs/prd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Detect a task directory that no Todo entry references

> Task version: v1
> Status: in_progress

## Goal

`hooks/repository-check` reports every task directory (active and
`achieved/`) whose path no `- Task:` line in `todo.md` names — a lost Todo
record must not leave orphaned documents invisible. Report only; the hook
never moves or deletes files.

## Background / Confirmed Facts

Measured on `main` = `5eba691`, 2026-09-23, worktree
`.worktrees/feat-orphan-task-dirs`. Nothing inferred.

**Incident (Notes, 2026-09-16):** while staging PR #28 for one task, Todo
entries for B/C/D were stripped; `git checkout -- TaskFlowDocs/todo.md`
then restored the file, but for a window the three directories had **no
Todo reference** (workspace only; restored same day). Historical example
still true on this tree: `TaskFlowDocs/achieved/2026-09-10-repository-document-placement/`
— never had a Todo entry in any commit.

**Direction (Notes):** only **directory → Todo**. Reverse (Todo → missing
directory) was measured empty on 2026-09-16; not part of this check unless
it costs nothing extra (see Open Questions).

**`ab381b` (done)** fixed isolation-before-documents and taught
`repository-check` to list **uncommitted** task artifacts. Those lines never
set `needs`. They do **not** answer “directory exists, Todo forgot it” —
committed and archived orphans are invisible to that loop today
(`TaskFlowDocs/*/` only, and only when not in `HEAD`).

**`repository-check` shape (hooks/repository-check):** read-only; artifact
section prints and leaves `needs` alone; final `STATUS: pass` (0) or
`needs-user-input` (2). Existing smoke sections: general status + uncommitted
artifacts without changing verdict.

**Todo `Task:` values that *do* reference a directory** (backticked):

- `TaskFlowDocs/<task>/`
- `TaskFlowDocs/achieved/<task>/`

Non-references: `Not promoted.`, `None — …`, template placeholders.

**Task directory =** has `prd.md` or `plan.md`. That already skips
`repository-docs/`, `todo.md`, and `achieved/` itself. Must also scan
`TaskFlowDocs/achieved/*/` — current loop does not.

**Survey on `5eba691`:** with that rule, **0 active + 0 achieved orphans**
among dirs that have core docs *except* the known historical achieved dir
if its Task: is still missing — counted in implementation smoke fixtures,
not by mutating real history here. (Fixture-driven; live tree may report
the known achieved orphan until a human adds a tombstone or accepts the
line.)

## Requirements

- **R1.** In `hooks/repository-check`, after the uncommitted-artifacts
section (or adjacent), report **orphan task directories**: every
`TaskFlowDocs/<id>/` and `TaskFlowDocs/achieved/<id>/` that has `prd.md`
or `plan.md`, for which no `- Task:` line in `TaskFlowDocs/todo.md` equals
that path with or without a trailing backtick slash.
- **R2.** Read-only. Never delete, move, or rewrite Todo/dirs.
- **R3.** Orphan findings **set `needs=1`** (STATUS `needs-user-input`,
exit 2) — a lost Todo record is actionable integrity, unlike the
informational uncommitted-artifact lines which stay `needs`-neutral.
- **R4.** Empty orphan set → no behavior change vs today for that condition
(does not by itself fail a clean repo that already passes).
- **R5.** Output names each path once under a clear heading (e.g.
`Orphan task directories:`) with one path per line.
- **R6.** Smoke: (a) fixture with an unreferenced active dir → report lists
it, status 2; (b) same dir referenced by `- Task:` → not listed; (c)
achieved/ orphan listed; (d) clean fixture with only referenced dirs →
no orphan section / still pass when nothing else is wrong; (e) existing
repository-check sections still green.
- **R7.** `bash hooks/smoke-test` → `ALL SMOKE PASSED`.

## Acceptance Criteria

- **A.** Fixture `TaskFlowDocs/2026-01-01-lost/{prd,plan}.md` + Todo with no
matching `Task:` → line contains that path; exit 2.
- **B.** Add `- Task: \`TaskFlowDocs/2026-01-01-lost/\`` → path gone from
orphan list.
- **C.** `TaskFlowDocs/achieved/2026-01-01-gone/` with core docs, no Task:
→ listed.
- **D.** Uncommitted-artifact fixture still reports staged/untracked and
does not require an orphan to exercise that path.
- **E.** Suite green; `bash -n hooks/repository-check`.

## In Scope

- `hooks/repository-check` orphan report.
- `hooks/smoke-test`.

## Out of Scope

- Auto-delete or auto-repair orphans.
- Reverse check (Todo → missing dir) as a hard requirement (optional
freebie only if free; see Q2).
- New hook binary.
- Changing uncommitted-artifact `needs` neutrality.
- Rewriting historical achieved records to invent Todo entries.

## Risks / Deferred Items

- Known historical achieved orphan may turn real repos to exit 2 until a
human records a tombstone/entry — **mitigate:** report is accurate;
fix is data, not code. Note in Change Log if live survey trips.
- `Task:` written without backticks would be missed — current repo uses
backticks for real paths; match backticked form only (R1) unless a
non-backticked path appears (survey: none for real dirs).

## Open Questions

1. Orphan sets `needs` — **Recommend: yes (R3)**; distinct from uncommitted
artifacts.
2. Also assert Todo → dir exists — **Recommend: no hard fail this PR**;
Notes said measured empty; add only if a free one-liner in the same
loop, still report-only. Default: skip to keep the diff small.
3. Live known achieved orphan — **Recommend: report it**; do not special-
case names.

## Version History

- v1 — planning.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Plan — Record Approval from a hook instead of hand-editing the five fixed fields

> Task version: v1
> Status: in_progress
> Status: completed

No spec required — small, self-contained task.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Record Approval from a hook instead of hand-editing the five fixed fields

> Task version: v1
> Status: in_progress
> Status: completed

## Goal

Expand Down
14 changes: 7 additions & 7 deletions TaskFlowDocs/todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -586,15 +586,15 @@ Every direct request or imported requireme
## Detect a task directory that no Todo entry references

- ID: TF-20260916-a357ee
- Status: inbox
- Status: in_progress
- Priority: normal
- Owner: Codex
- Source: user review
- Added: 2026-09-16
- Updated: 2026-09-16
- Updated: 2026-09-23
- Goal: Detect a task directory that no Todo entry references, so a lost Todo record cannot leave orphaned task documents behind.
- Task: Not promoted.
- Next action: Clarify whether this belongs in the existing `hooks/todo-check` or is a separate check; then promote.
- Task: `TaskFlowDocs/2026-09-23-orphan-task-dirs/`
- Next action: Complete PRD / Spec / Plan and request approval.
- Notes: 发现于 2026-09-16 —— 提交 PR #28 时为让提交只含任务 A 而摘掉 B/C/D 的 Todo 条目,随后一次 `git checkout -- TaskFlowDocs/todo.md` 把工作区文件整体回退,三条条目一度丢失(同日已按原样补回),而三个任务目录始终在 `TaskFlowDocs/` 下,形成「目录存在、无 Todo 指向」的孤儿态(仅工作区,未进入任何提交)。同一形态在历史里也有一例:`TaskFlowDocs/achieved/2026-09-10-repository-document-placement/`,全部历史中从未有过对应的 Todo 条目。目前该缺口无自动检查兜住。注意:只查「任务目录 → Todo」这一个方向;反方向(Todo 条目指向不存在的目录)本轮已实测为空。2026-09-16 追问:本条与 `TF-20260916-ab381b` 是同一根因的两个方向——孤儿目录是「文档先于隔离产生」的结果,`ab381b` 修根因并在 `hooks/repository-check` 里报告错位产物;本条仍是更广的历史审计(含已提交、已归档的目录),是否仍要独立成检查待定。

## Publish TaskFlow v1.0.6 with the CodeBuddy host, the Todo merge-drop audit, and the release version check
Expand Down Expand Up @@ -702,15 +702,15 @@ Every direct request or imported requireme
## Record approval in the plan from a hook instead of hand-editing four fixed-forma

- ID: TF-20260918-454ac4
- Status: in_progress
- Status: done
- Priority: normal
- Owner: Codex
- Source: user request
- Added: 2026-09-18
- Updated: 2026-09-23
- Goal: Record approval in the plan from a hook instead of hand-editing four fixed-format fields, and fix hooks/version writing an Approval block that disagrees with hooks/task's template.
- Task: `TaskFlowDocs/2026-09-23-task-approve/`
- Next action: Complete PRD / Spec / Plan and request approval.
- Task: `TaskFlowDocs/achieved/2026-09-23-task-approve/`
- Next action: None — completed and archived.
- Notes: **2026-09-18 用户提出**:手改 Approval 块能否自动化。判定——`## Approval` 的字段里只有 `Approved by` 是语义的(必须由人表态),其余都可推导:`Status` 是该子命令的动词,`Approved at` 是当天日期(hook 已有 `today`),`Approved version` 直接读 plan 自己的 `> Task version:` 行,`Approved scope` 由存在的核心文档推出。`skills/taskflow/SKILL.md` 已把模板钉成「`- Approved by:` 起的四行」,格式无需 Agent 判断。
**先修一个现成的自相矛盾**:`hooks/version` 的重置只写 `- Approved by/at/version/scope: pending` 四条,**不写 `- Status:`**;而 `hooks/task` 的模板是**五**行、带 `- Status: requested`。于是经 `version` 迁移过的任务,Approval 块是 version 的字段集加上一条滞留在旧值的 `- Status:` 行——两个 hook 对同一块内容的形状意见不一致。**本任务就是实例**:v1→v2 后 `- Status:` 留在 `checking` 一路没人管,直到 `complete` 读它才发现对不上(`require_approval` 用的是 `grep -qx -- "- Status: approved"`)。
**时间格式也打架**:模板写 `YYYY-MM-DD HH:mm +08:00`,`version` 复位只写 `pending`。若自动化,`today` 目前只有 `+%Y-%m-%d`,要扩出分钟与时区。
Expand Down
29 changes: 29 additions & 0 deletions hooks/repository-check
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,35 @@ else
echo " branch or moving the work to its own working tree is what removes the report."
fi

# A task directory (active or achieved) that no Todo `- Task:` line names is a
# lost Todo record beside live documents — actionable integrity, unlike the
# informational uncommitted-artifact lines above. Report only: never delete.
# Sets `needs`.
orphans=""
if [ -d TaskFlowDocs ]; then
refs=""
if [ -f TaskFlowDocs/todo.md ]; then
refs="$(sed -n 's/^- Task: `\([^`]*\)`.*/\1/p' TaskFlowDocs/todo.md | sed 's|/*$||')"
fi
for dir in TaskFlowDocs/*/ TaskFlowDocs/achieved/*/; do
[ -d "$dir" ] || continue
[ -f "$dir/prd.md" ] || [ -f "$dir/plan.md" ] || continue
name="${dir%/}"
if [ -z "$refs" ] || ! printf '%s\n' "$refs" | grep -qxF "$name"; then
orphans="$orphans- $name
"
needs=1
fi
done
fi
if [ -z "$orphans" ]; then
echo "Orphan task directories: none"
else
printf 'Orphan task directories:\n%s' "$orphans"
echo " A directory with prd.md or plan.md that no Todo - Task: line names."
echo " Restore or recreate the Todo entry, or archive/remove the directory deliberately."
fi

if [ "$needs" -eq 1 ]; then
echo "STATUS: needs-user-input"
exit 2
Expand Down
Loading
Loading