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
|
#+TITLE: Monitor Inbox Workflow
#+AUTHOR: Craig Jennings & Claude
#+DATE: 2026-05-31
* Overview
Keep the project's =inbox/= responsive: notice handoffs on a cadence, triage each one, decide whether to act now or file it, and reply to the sender. This workflow is the /when, how-often, and act-vs-file/ layer. The per-item disposition mechanics — the value gate, the implement/fold/file classification, the per-source rejection flow — live in [[file:process-inbox.org][process-inbox.org]] and are not duplicated here. Think of it as: monitor-inbox decides /that/ an item gets handled and /how I respond/; process-inbox decides /what disposition/ each item gets.
The gap this closes: handoffs that arrive mid-session used to sit unseen until the user asked or the next startup ran. A handoff the sender can't see being handled trains them to escalate around the inbox channel.
* Preconditions — before starting
Never begin inbox monitoring on a dirty worktree or with a failing test suite. A dirty tree means the auto-commit at the end of an executed item sweeps up unrelated changes; a red suite means you can't tell whether the monitor broke something. At the start of the workflow, check both:
1. =git status --porcelain= is empty (clean worktree).
2. A full test run is all green (=make test= here, or the project's full-suite command).
If the worktree is *dirty*: offer to commit the pending changes in discrete, logical batches before starting. If the suite is *red*: offer to investigate the failures first. Surface the blocker with inline numbered options per =interaction.md= and wait — monitoring does not start until the tree is clean and the suite is green.
* When to Use This Workflow
Trigger phrases:
- "monitor the inbox" / "watch the inbox" — *the defined meaning:* run one process-inbox pass now, then loop process-inbox every 15 minutes (see Cadence). Not an opt-in extra — the phrase *is* the loop.
- "respond to the handoffs" / "handle the handoffs" — a single pass now, no loop.
Cadence auto-trigger (ambient, always on): check at every task boundary during a session, even when no loop is running — see Cadence below.
* Cadence — how often to check
*"Monitor the inbox" = run now, then loop every 15 minutes.* When Craig says monitor or watch the inbox, do one process-inbox pass over any pending handoffs immediately, then start the loop:
#+begin_src
/loop 15m check the inbox with inbox-status and run process-inbox.org over any pending handoffs
#+end_src
Each firing runs the cheap =inbox-status= check first and only does a full process-inbox pass when items are pending. The loop is the monitoring; it runs until Craig stops it or the session ends. Honor the Preconditions gate before the first pass and the Close-out gate when the loop stops.
*Ambient task-boundary check (always on, even without a loop).* After finishing a unit of work, before reporting back or asking "what's next," run the cheap status check:
#+begin_src bash
.ai/scripts/inbox-status -q
#+end_src
Exit 1 means handoffs are pending — list them (drop =-q=) and process per process-inbox.org. Exit 0 means clean; say nothing. This is one =find=; it costs nothing to run often, and it's the fix for handoffs piling up unseen during long sessions.
*Startup and wrap-up already cover their ends.* Startup Phase C processes a non-empty inbox; the wrap-up sanity check refuses to wrap with unprocessed handoffs. The task-boundary cadence fills the middle.
*Mid-task arrivals.* If a handoff lands while you're mid-task and it's urgent (blocks the current work, or is time-sensitive), surface it right away. Otherwise batch it to the next task boundary so the current work isn't thrashed.
* The act-vs-file decision
Every accepted handoff (one that clears process-inbox's value gate) is then either acted on now or filed as a task. The rule, and how to surface it:
*Act immediately — and just do it, no asking — when all of these hold:*
- *Clear* — the action is unambiguous; no design decision or option-choice is needed.
- *Bounded* — small, finishable this session, ideally a tight file set.
- *Low-risk and verifiable now* — not a risky change to load-bearing infra (or trivially revertible), and testable/lintable this session.
- *In-scope and safe* — within this project, not destructive or outward-facing without confirmation, not across a project boundary.
- *Cheaper than deferring* — doing it now costs less than filing plus re-triaging later.
When you decide to act, queue the work and do it. Don't ask first.
*Exception:* a proposal to change a shared asset (template workflow, rule, skill, synced script) or a substantive convention never qualifies for silent act-now, however clear and bounded it looks — it routes through process-inbox's *Skeptical Review*, which carries its own approval (or, in a no-approvals session, park) step.
*File a task when any of these hold:*
- It needs a judgment call, a design decision, or an option the user would pick.
- It's large, multi-session, or sprawls across many files.
- It's blocked (a dependency, an external thing, the user is away).
- It's risky enough to want the user's eyes before it lands.
- It's off the session's active goal and acting now would derail it (file and keep going, unless it's urgent).
When you decide to file, *ask first* — inline numbered options per =interaction.md=, with *filing as option 1 (the recommendation)* and *"do it now" as option 2*:
#+begin_example
<handoff> wants <X>. My read: file it (needs <reason>).
1. File as a TODO ([#?] :tags:) — Recommended
2. Do it now instead
3. Something else
Pick a number.
#+end_example
*Always ask if you're unsure* which side of the line an item falls on. Decisiveness on clear act-now items is the point of the rule; the ask is for genuine ambiguity and for filing.
** Executing in no-approvals mode
When Craig has put the session in no-approvals mode, an accepted item may be implemented automatically — but only when all three of these hold:
1. *Agreed* — you've run the value gate and the full Skeptical Review and concluded the change should be done, not merely that it's harmless.
2. *Quick* — the whole implementation, including verification, is under ~15 minutes.
3. *Solo* — you can carry it end to end without a decision from Craig. Manual verification you perform yourself is fine; needing Craig to choose an option, approve a design, or resolve an ambiguity is not.
All three → implement it, verify, then commit and push at the end of that item (the Step 0 reconcile and pre-push check from =commits.md= still run). Miss any one and it doesn't self-apply: a shared-asset or convention change needs Craig's decision, so it fails *solo* and routes to process-inbox's defer-and-stage park; an oversized item fails *quick* and gets filed.
* Replying to handoffs
A handoff came from another project's agent (or the user). Close the loop:
- *Accepted and acted on* — send a confirmation to the sender via =inbox-send <sender> --text "..."=, naming what landed and the commit, so they're not left guessing (they can't see this project's git log). =inbox-send= excludes the current project as a target, so a self-sourced item is handled in-session, not sent.
- *Accepted and filed* — a short confirmation that it's filed and where, so the sender knows it wasn't dropped.
- *Rejected* — always state the why (which value-gate question failed), per process-inbox's per-source rejection flow.
Cross-project boundary: never act on a file under another project's =.ai/= scope from here — route it back as a handoff (see =cross-project.md=).
* The inbox-status script
=.ai/scripts/inbox-status= lists unprocessed handoffs and exits nonzero when any are pending. Exclusions match the wrap-up sanity check (=.gitkeep=, =lint-followups.org=, =PROCESSED-*=). Exit 0 = clean, 1 = pending, 2 = no inbox/ or bad usage. Use =-q= for the count-only form the cadence check calls.
* Close out — before finishing
End the workflow the way it started: clean worktree, green suite. Before stopping the loop or reporting the pass done:
1. Commit or revert everything left in the worktree — nothing uncommitted remains.
2. Run the full test suite once more and confirm all green.
If either can't be satisfied — a half-done item, a failure introduced during the pass — surface it rather than leaving it. The next monitor run assumes a clean, green starting state (the Preconditions gate), so handing it a dirty tree or a red suite breaks the next run before it begins.
* Living Document
Tune the cadence if task-boundary checking proves too frequent or too sparse in practice. Refine the act-vs-file criteria as edge cases recur. If the background-monitor loop becomes a common pattern, capture the interval that worked. The decision rule itself — act-now is silent, filing asks with file-as-option-1, ambiguity asks — is the stable core (set by Craig, 2026-05-30).
|