1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
|
# Todo Entry Format
Applies to: `**/*.org` (org-mode todo and inbox files)
How task entries are structured in org-mode todo files (`todo.org`,
`inbox.org`, any GTD-style org file). Same shape across every project.
## The Rule
A todo entry has two parts:
1. **Heading** — terse subject naming just the topic. No action verbs, no
sentence-shape, no dates. Tags belong on the heading line.
2. **Body** (optional) — fuller description: action verbs, context,
rationale, source/origin, links, deadlines. Used when the topic alone
isn't enough.
When the topic alone is enough, skip the body entirely.
## Format
** TODO [#A] Terse topic phrase :tag1:tag2:
Optional body — fuller description, action verbs, context, links.
Multi-paragraph body is fine when context warrants it.
## Examples
Good:
** TODO [#A] Blacken + Prettier config from Vrezh
Ask Jason to implement the formatter config Vrezh sends over.
** TODO [#B] TAK-server plugin user scenarios :quick:
Develop with Eric, send to Nate Soule for review.
Out of the 2026-05-13 RTX<>DeepSat sync.
Bad (sentence-shaped heading, details crammed in):
** TODO [#B] Develop TAK-server plugin user scenarios with Eric, send to Nate :quick:
## Why
The org agenda view shows the heading. A short heading is scannable; a
sentence-shaped one runs off the edge of the agenda buffer, and the
context that mattered ends up in the truncated tail. The body is always
reachable by visiting the entry — push everything beyond the topic there.
## How to apply
When adding a new task:
1. Pick the smallest noun phrase that names the topic.
2. If anything else is worth saying, put it in the body.
3. Tags go on the heading line, not in the body.
When restructuring an existing entry that's already sentence-shaped, split
it: keep the topic as the heading, move the rest to the body.
## Completion — depth-based
How a finished `TODO` / `DOING` task is closed depends on its depth in the outline. The rule is *depth-based*, not keyword-based, because the agenda truncates beyond level-2 and the visibility tradeoff flips at that boundary.
### Top-level tasks (`*` and `**`) — stay task-shaped
A completed `*` section or `**` task keeps its `TODO`/`DOING`-shape so it remains visible in the agenda as a record of what shipped:
1. Change the keyword to `DONE` (or `CANCELLED` if the task was abandoned rather than completed).
2. Add a `CLOSED: [YYYY-MM-DD Day]` line directly under the heading. Use `date "+%Y-%m-%d %a"` to generate.
3. Leave the original heading text, priority cookie, and tags intact.
4. Optionally add a one-line resolution note in the body.
The entry is then a candidate for `--archive-done` in the wrap-up cleanup, which moves level-2 `DONE`/`CANCELLED` subtrees from the project's "Open Work" section into "Resolved."
**Example:**
** TODO [#B] Convert <cj structure template to universal yasnippet
becomes
** DONE [#B] Convert <cj structure template to universal yasnippet
CLOSED: [2026-05-15 Fri]
### Sub-tasks (`***` and deeper) — rewrite to a dated event-log entry
A completed sub-task disappears as a task and becomes an in-place event-log entry under its parent. The parent's subtree organically grows into a chronological history of what landed without the agenda being cluttered by a long tail of nested `DONE` lines.
1. Replace the heading with `<same depth> YYYY-MM-DD Day @ HH:MM:SS -ZZZZ <past-tense description>`.
2. Generate the timestamp with `date "+%Y-%m-%d %a @ %H:%M:%S %z"`.
3. Reword the original imperative title into the past-tense action that landed. Trim or restate if the original wording doesn't fit the action.
4. Drop the `TODO`/`DOING` keyword, the priority cookie, and the tags. The body stays as the record of what was done (if useful).
**Example:**
*** TODO [#B] Wire yasnippet for universal availability :refactor:
becomes
*** 2026-05-15 Fri @ 12:58:08 -0500 Wired yasnippet for universal availability
### Why depth-based
The agenda view (`org-agenda`) shows entries at the section + top-task level. Letting `**` tasks stay task-shaped preserves their visibility as "things that recently shipped." Letting `***+` sub-tasks flip to dated entries keeps the agenda from being clogged with a long list of completed sub-tasks at every depth — those become history within their parent instead.
`VERIFY` is the documented exception: it follows the dated-rewrite rule at **all** depths (including `**`), because a resolved VERIFY is an answered question rather than a finished task. See the VERIFY section below.
## VERIFY tasks
`VERIFY` is the keyword for "waiting on Craig's input" — open questions,
pending decisions, drafts awaiting approval. The placement and completion
rules below are stricter than normal TODO tasks because VERIFYs are
open-question placeholders, not regular tasks.
### Placement — top-level or first-level child only
A VERIFY task lives at exactly one of two depths:
1. **Top-level** under the relevant section (e.g., `** VERIFY ...` directly
under `* Work Open Work`).
2. **First-level child** of a parent task (e.g., `*** VERIFY ...` under a
`** TODO` / `** DOING` parent).
Never deeper. A VERIFY at `****` or below is buried — the agenda view
collapses it under its grandparent and Craig stops seeing it. When you
catch a VERIFY at `****+`, flatten it up to one of the two allowed depths.
The goal is a flat, scannable task list: the parent task is the topic; its
VERIFYs are the open threads under that topic; the dated history sits as
log entries (which *can* be deeper).
### Creating a new VERIFY — sibling of its trigger
When you add a new VERIFY task, place it as a **sibling of the heading
that triggered its creation** — not as a child of that heading.
The trigger is whatever surfaced the open question:
- A cj annotation that asks something or marks a pending decision →
trigger is the heading the annotation sits under.
- A task body or sub-task that uncovered an unanswered question while you
were working it → trigger is that task.
- A draft awaiting Craig's sign-off → trigger is the draft's parent task.
Depth-wise, this means:
- Trigger at `**` → new VERIFY at `**` (top-level sibling under the
section).
- Trigger at `***` → new VERIFY at `***` (first-level-child sibling under
the same `**` parent).
- Trigger at `****` or deeper → VERIFY can't follow it there (Placement
rule above). Climb the VERIFY up to `***` and surface the buried
trigger as a candidate to flatten.
- Trigger at `*` (a top-level section) → VERIFY goes at `**` (top-level
task under the section).
File placement: insert the new VERIFY *after* the trigger's entire
sub-tree ends — i.e., after any sub-tasks, dated log headers, or draft
sub-headings the trigger already contains. This keeps everything under a
`**` parent flat: sub-tasks, dated logs, and VERIFYs all live as
siblings at `***`, never burrowing deeper.
The sibling rule is the active force that keeps `todo.org` flat. Without
it, VERIFYs accumulate one level deeper than their trigger every time —
turning a clean parent tree into a long pole of nested sub-headings.
### Completion — dated rewrite + content replacement
When a VERIFY resolves, **rewrite the heading and body together** at the
same depth — regardless of whether the VERIFY is at `**` or `***`:
1. **Replace the heading.** Drop the `VERIFY` keyword (and any priority
cookie / tags) and replace with a timestamp + short description:
*** 2026-05-15 Fri @ 14:00:00 -0500 <what was answered or done>
Generate the timestamp with `date "+%Y-%m-%d %a @ %H:%M:%S %z"`.
Match the original depth (a `**` VERIFY becomes `** YYYY-MM-DD ...`;
a `***` VERIFY becomes `*** YYYY-MM-DD ...`).
2. **Replace the body.** Drop the original question/instruction prose and
replace with either:
- **The information Craig provided** (when the VERIFY was a question
— paste the answer, a quote, a link, whatever resolved it), or
- **A description of the action taken** (when the VERIFY was an
instruction or pending-decision marker — what was done, when, where
the artifact lives).
The completed VERIFY becomes an in-place event log entry. The original
question is preserved by the dated heading + body shape; anyone scanning
the agenda or `git log` can see what was asked and what landed.
**Note on the top-level case.** Regular `**` DONE tasks stay task-shaped
with a `DONE` keyword + `CLOSED:` line per *Completion — depth-based*
above. VERIFYs at `**` are the exception — they convert to dated log
entries on completion because a resolved VERIFY isn't a "done task," it's
an answered question. The dated-rewrite rule wins for VERIFYs at all
depths.
### Don't leave stale placeholders
A well-named VERIFY heading carries the question on its own. Don't append
`cj: <fill in>` placeholder lines under the heading — Craig adds his own
cj comment (a `#+begin_src cj: ... #+end_src` block) when he's ready to
answer, and that's the trigger to process the response. Empty placeholders
are noise that pollute his `cj:` greps.
### Examples
**Top-level VERIFY, before / after:**
** VERIFY What's our position on the BBN NDA reciprocal-term length?
** 2026-05-15 Fri @ 14:00:00 -0500 BBN NDA — standard 2-year reciprocal terms confirmed
Per Nerses 2026-05-15 (Slack DM D0AAAEW3BS4): DeepSat's standard NDA template uses 2-year reciprocal. Sent to BBN legal for sign-off.
**First-level child VERIFY, before / after:**
** DOING [#A] Kostya's contract :admin:kostya:
*** VERIFY Confirm Kostya's basis — part-time hr/week or full-time?
** DOING [#A] Kostya's contract :admin:kostya:
*** 2026-05-15 Fri @ 14:00:00 -0500 Kostya basis — part-time, 20 hr/week
Nerses confirmed 5/15 13:30 CDT: Kostya runs at 20 hr/week part-time, mirroring Vrezh's structure. Plugged into Exhibit A § 2 of the contract draft.
|