diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-28 08:56:24 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-28 08:56:24 -0500 |
| commit | 0c7eb59f813b5572cc32beb6d2dd09355639cbfc (patch) | |
| tree | 188aa3f25b4e1a02c26fd79a17fa2d68ec5c26a1 /.ai/workflows/process-inbox.org | |
| parent | 8dfbe5c4d148b9bced5ffd632521566cf9255aa0 (diff) | |
| download | rulesets-0c7eb59f813b5572cc32beb6d2dd09355639cbfc.tar.gz rulesets-0c7eb59f813b5572cc32beb6d2dd09355639cbfc.zip | |
feat(workflows): add process-inbox.org with value-gate discipline
Generic process-inbox workflow at claude-templates/.ai/workflows/ and
mirror. Owns inbox discipline across every project: items are ideas to
evaluate, not orders to execute, and earn a place in todo.org or git
history only when they pass a three-question value gate.
The gate (Phase B):
- Advances an existing TODO (look up by topic).
- Improves how the project works (architecture, workflows, tooling,
rule hygiene).
- Serves the project's stated mission (read from notes.org
Project-Specific Context).
One yes accepts. Three nos reject.
Per-source rejection flow (Phase D):
- From Craig: state in chat, wait for override.
- From another project: write a response via inbox-send naming which
gate question failed plus any reconsideration condition. Silent
rejection on a handoff is worse than no reply.
- From a script or automated system: just delete.
Phase B.1 gates filing on priority-scheme presence. If todo.org has a
scheme at the top, file with cookie + mandatory type tag + optional
effort/autonomy tags. If not, surface a one-sentence nudge to adopt
one (or to skip grading and flag the gap in the commit).
Phase D within accepts splits implement-now / fold-into-existing /
file-as-TODO so the inbox doesn't default to inflating todo.org for
every item that passes the gate.
Phase E stamps :LAST_INBOX_PROCESS: in notes.org Workflow State if the
section exists.
startup.org Phase C step 2 now delegates here instead of inlining the
inbox-processing language. INDEX entry under Tasks and planning lists
the full set of trigger phrases.
Diffstat (limited to '.ai/workflows/process-inbox.org')
| -rw-r--r-- | .ai/workflows/process-inbox.org | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/.ai/workflows/process-inbox.org b/.ai/workflows/process-inbox.org new file mode 100644 index 0000000..c6b3f79 --- /dev/null +++ b/.ai/workflows/process-inbox.org @@ -0,0 +1,172 @@ +#+TITLE: Process Inbox Workflow +#+AUTHOR: Craig Jennings & Claude +#+DATE: 2026-05-28 + +* Overview + +Inbox items are *ideas to evaluate*, not orders to execute. They arrive from Craig (typed directives saved as files), from other projects (handoffs via =inbox-send=), and from scripts/automated systems. Each is a proposal. An item earns a place in =todo.org= or git history only when it passes the value gate: it advances an existing task, improves how the project works, or serves the project's stated mission. + +The workflow is the disposition discipline. Read each item, evaluate honestly, apply the decision, then notify the sender if it was a project handoff and you're rejecting. Silent rejection on a handoff is worse than no reply. + +* When to Use This Workflow + +User triggers: + +- "process inbox" / "process the inbox" +- "handle the inbox" +- "what's in inbox" / "what's in the inbox" +- "let's clear the inbox" / "let's process the inbox items" + +Auto-invocation: + +- Startup =Phase C step 2= delegates here when the inbox is non-empty. Don't ask Craig — just run it. + +Do *not* invoke this for inbox items that are clearly out-of-scope for the project — those are cross-project routing problems, handled per the cross-project boundary rule in =protocols.org=. + +* The Value Gate + +Every inbox item passes through three questions. One *yes* is enough to accept. + +1. *Does it advance an existing TODO?* Look up by topic in =todo.org='s open work. If the item extends a filed task, fold it in. If it implements a filed task, do the work. +2. *Does it improve how the project works?* Architecture cleanup, workflow refinement, tooling, rule hygiene, drift detection — anything that makes the project itself more effective. +3. *Does it serve the project's stated mission?* Read =notes.org= *Project-Specific Context* if the mission isn't obvious from the working directory and current task. The item should advance that mission, not orbit it. + +Three *no*s means reject. The rejection isn't lazy — an idea that doesn't help any current task, doesn't improve the system, and doesn't serve the mission is genuine noise, and accepting it inflates =todo.org= without payoff. + +* Phase A — Inventory (one parallel batch) + +Issue these reads in one parallel batch: + +1. List =inbox/= excluding =.gitkeep= and =PROCESSED-*= prefixes (use =\ls -la inbox/= per the protocols.org exa-alias note). +2. Read =notes.org= *Project-Specific Context* if mission isn't already loaded in the session. +3. Read =todo.org='s top-of-file priority scheme if present (look for a =* Priority and Tag Scheme= section or similar between the intro and the first =* <Project> Open Work= header). + +For each inbox file, parse the filename for sender. Two common patterns: + +- =YYYY-MM-DD-HHMM-from-<sender>-<topic>.<ext>= — from another project via =inbox-send=. +- =<topic>.org= — typically from Craig directly, or from a script. + +Note the file type. =.eml= files need the extract script (not raw =Read=): + +#+begin_src bash +# View mode +python3 .ai/scripts/eml-view-and-extract-attachments.py inbox/<file>.eml + +# Pipeline mode (extract attachments to a directory) +python3 .ai/scripts/eml-view-and-extract-attachments.py inbox/<file>.eml --output-dir assets/<target>/ +#+end_src + +Everything else, read directly. + +* Phase B — Evaluate each item + +For each inbox file: + +1. *Read it.* For substantive proposals (org files with TODO entries, design notes, multi-section docs), the full read is the right move. For short FYIs and one-liner asks, skim. +2. *Identify the shape.* Is it an instruction, a question, a proposal, an FYI, or a handoff? Shapes guide disposition. +3. *Apply the value gate.* Three questions above. One yes → candidate accept. Three nos → candidate reject. +4. *Within accept, classify:* + - *Implement now* — small, scoped, clear, no design call required. The work is the disposition. + - *Fold into existing TODO* — the item extends a task already filed; update the TODO body and link the inbox content if substantive. + - *File as TODO* — substantive but waits, or needs design/triage before implementation. +5. *Within reject, classify by source:* + - *From Craig* — push back honestly in chat. State why you won't implement. Offer the conditions under which you would, if any. Wait for Craig to override or accept. + - *From another project* — write a response file naming the rejection rationale and (optionally) the condition under which you'd reconsider. Deliver via =inbox-send <sender> --file <response>= per the cross-project handoff convention. + - *From a script or automated system* — just delete; no notification needed. + +* Phase B.1 — Priority-scheme check + +This gates Phase C filing when there are accept-and-file items. + +Check whether =todo.org= has a top-of-file priority scheme (an explicit legend defining =[#A]= through =[#D]= semantics and mandatory/optional tag conventions). + +- *Scheme present* — file new TODOs per the scheme. Every TODO gets a priority cookie matching the legend's rules, the mandatory type tag, and any applicable effort/autonomy tags. +- *Scheme absent* — surface one sentence: "This project has no priority scheme. We should adopt one before filing the new TODOs from this inbox pass — want me to propose one based on the rulesets scheme?" If Craig says yes, do that first (the =/research-priority-scheme= research subagent pattern in rulesets is the reference). If Craig says no, file the TODOs without grading but flag in the commit message that they're un-prioritized pending a scheme. + +The point is to avoid adding ungraded =TODO= entries to a project that's never agreed on what =[#A]= means. + +* Phase C — Surface dispositions + +Numbered options inline per =interaction.md= (no popup). Recommendation at item 1. + +Batch trivial items (one-line rejections of script noise, obvious file-as-TODO accepts where the scheme is already settled) into a single confirm-all prompt. Walk substantive items one at a time so the decision is visible. + +Per-item template: + +#+begin_example +<filename> from <sender>: <one-line summary> +Value-gate read: <yes/no on each of the three questions, one phrase each> +Disposition recommendation: <implement / fold into <TODO> / file [#X] :tags: / reject> + +1. <recommendation as item 1> +2. <alternative> +3. Defer — leave in inbox under PROCESSED-<topic>.<ext> until <condition> +4. Something else +#+end_example + +For pure FYIs that need no action, surface as a single line and recommend delete-with-acknowledgment. + +* Phase D — Apply + +Apply each disposition. The flow is autonomous past Craig's Phase C approval. + +** Implement-now + +Do the work. Commit per the project's commit flow. Delete the inbox file. The commit message references the inbox item by filename so the provenance lands in =git log=. + +** Fold into existing TODO + +Update the parent TODO's body with a dated reconciliation sub-entry per =todo-format.md= (=*** YYYY-MM-DD Day @ HH:MM:SS -ZZZZ <what landed>=). Move substantive content to =docs/design/<date>-<topic>.<ext>= if it's worth keeping; reference from the TODO body. Delete the inbox file. + +** File as TODO + +Add the TODO under =* <Project> Open Work= with priority + tags per Phase B.1. Body summarizes the proposal and links the inbox content if it's been moved to =docs/design/=. Delete the inbox file (or move it to =docs/design/= first if the content survives). + +** Reject from Craig + +State the rejection in chat clearly: what you won't implement, why, and the conditions (if any) under which you would. Wait for Craig's override or acknowledgment. The inbox file stays until Craig confirms — if he overrides, re-enter Phase D as accept; if he acknowledges the rejection, delete the file. + +** Reject from another project (handoff) + +Write the response file at =/tmp/inbox-response-<topic>.org=. Contents: + +- Heading naming the original handoff and date +- One paragraph: the rejection rationale (which value-gate question failed and why) +- One paragraph: the condition under which you'd reconsider, if such a condition exists. If the answer is "never, this misreads the project's mission," say so directly. + +Deliver via =inbox-send <sender> --file /tmp/inbox-response-<topic>.org=. The =inbox-send= script (per =cross-project.md=) handles the from-prefix, date stamp, and target inbox path. + +Delete the local inbox file after the response lands in the sender's inbox. + +** Reject from script or automated system + +Just delete. No notification. + +** Defer + +Rename in place to =inbox/PROCESSED-<original-filename>= and add a brief comment line at the top: =# Deferred YYYY-MM-DD: <condition>=. Don't accumulate deferred items indefinitely — sweep them on a future =process-inbox= run when the condition is met or the deferral has aged out. + +* Phase E — Close out + +Verify =inbox/= is empty (excluding =.gitkeep= and any intentional =PROCESSED-*= files). Run =\ls -la inbox/= and confirm. + +Update the session log per =protocols.org= with one short paragraph summarizing this pass: count processed, count accepted (implement/fold/file split), count rejected (Craig/handoff/script split), and the commit SHA if a commit landed. + +Stamp =:LAST_INBOX_PROCESS:= in =notes.org='s *Workflow State* section if it exists, so future workflows that gate on freshness can read it. Same format as =:LAST_AUDIT:= (=YYYY-MM-DD=). + +* Common Mistakes + +1. *Treating items as orders.* Inbox content is a proposal. The value gate is the rule. Implementing every item without evaluation inflates =todo.org= and trains senders to keep sending noise. +2. *Filing without applying the value gate.* "File as TODO" is not a default — it's the disposition for proposals that pass the gate but wait. A reject is also a valid file-as-TODO answer to nothing. +3. *Filing raw TODOs when the project has a priority scheme.* Phase B.1 is mandatory when the scheme exists. An un-graded TODO in a project with a legend is a defect. +4. *Silently deleting a project handoff.* Send a response. The sender's next session sees the response in their inbox and learns the rejection rationale. Silent rejection trains the sender to escalate to Craig instead of through the inbox channel. +5. *Pushing back on a Craig directive only to immediately implement it anyway.* If you genuinely think Craig is wrong, say so and wait for his call. If you don't, just do the work — don't theatre the pushback. +6. *Skipping the implement-vs-fold-vs-file classification.* Defaulting every accept to "file as TODO" turns the inbox into a queue that flows into =todo.org= without filtering. Small, scoped, clear items get implemented now; substantive proposals get filed; extensions to existing work get folded. +7. *Not propagating value-gate failure to the response.* When you reject a handoff, the response should name *which* gate question failed (advances no current task / doesn't improve the project / doesn't serve the mission) so the sender can recalibrate, not just resend. +8. *Forgetting to delete the inbox file after acting.* The inbox should be empty when this workflow ends. Files left behind become noise on the next startup. + +* Living Document + +Refine the value gate's three questions if the project's mission sharpens. Tune the per-source rejection-response template if =inbox-send= response loops surface a pattern. Add new auto-classification shortcuts if certain item shapes (e.g. routine FYIs from a script) become common. + +The workflow is shaped by use. The principle that inbox items are *ideas to evaluate* is the part that doesn't change. |
