diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-23 23:06:46 -0400 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-23 23:06:46 -0400 |
| commit | 24ca58d764dbcc2bad57a914a10e9e9b89a3f66e (patch) | |
| tree | dc3ab8db840b1562db36cc048e44a391e31fa73f /.ai/workflows/process-inbox.org | |
| parent | 27da1f1d3290314d32455eac4e049118b00a7a13 (diff) | |
| download | rulesets-24ca58d764dbcc2bad57a914a10e9e9b89a3f66e.tar.gz rulesets-24ca58d764dbcc2bad57a914a10e9e9b89a3f66e.zip | |
feat(inbox): consolidate three inbox workflows into one engine
I merged process-inbox, monitor-inbox, and inbox-zero into one inbox.org engine. A shared core (value gate, skeptical review, disposition ladder, reply discipline, capture-guard, priority-scheme check) holds the logic that used to be duplicated and cross-referenced across the three files. Each mode (process, monitor, roam) references the core by name instead of restating it.
Every trigger phrase still works, now routing to a mode, so there's nothing to relearn. I added the interactive auto inbox zero mode: ask for an interval, run roam mode on /loop, acknowledge-only on an empty cycle, surface a find to a queue gated on a yes. The fully-unattended /schedule pass stays vNext, tracked separately.
I repointed every live caller (INDEX, protocols, startup Phase C, wrap-up Step 3, triage-intake, broadcast) at inbox.org and its modes, then deleted the three old files. triage-intake and no-approvals stay separate by design. The value gate, dispositions, capture-guard, and reply discipline all behave as before.
Built from the Ready spec. Workflow-integrity and sync-check pass on both the canonical and mirror trees, the stale-reference grep is clean, and the full suite is green.
Claude-Session: https://claude.ai/code/session_017PtX1nt1rtYVATuzmzBS4f
Diffstat (limited to '.ai/workflows/process-inbox.org')
| -rw-r--r-- | .ai/workflows/process-inbox.org | 220 |
1 files changed, 0 insertions, 220 deletions
diff --git a/.ai/workflows/process-inbox.org b/.ai/workflows/process-inbox.org deleted file mode 100644 index 687767e..0000000 --- a/.ai/workflows/process-inbox.org +++ /dev/null @@ -1,220 +0,0 @@ -#+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. - -* The Skeptical Review (every arriving task and file) - -The value gate decides whether an item is worth taking. This review decides whether what it proposes is *right*, *complete*, and *as simple as it should be*. Run it on every task and file that arrives in the inbox — not only shared-asset change proposals. Pure FYIs and replies that ask for nothing skip it. - -Approach the file with curiosity and skepticism. Work through, in writing — the core pass on every item: - -1. Is the request actually right — does it do what it claims, and is the claim correct for this project? -2. Is it complete, or does it leave a gap — an unhandled case, a missing step, an untested path? -3. Should it be simpler? -4. Can it be enhanced to be more effective than as proposed? -5. Does it conflict with any existing instruction — workflows, skills, rules, protocols, CLAUDE.md? - -When the item proposes a change to shared assets — template workflows, rules, skills, scripts, anything synced to consuming projects — or to a substantive convention, add the cross-project battery. It arrived from one project's context; you're evaluating it for all of them: - -6. Does this make sense for *all* consuming projects, or just the sender's situation? -7. How does it change a common activity Craig performs — better, worse, or differently than the sender assumed? -8. Plus at least three more questions specific to this change — what breaks for artifacts already using the old shape, what tooling interacts with it, what's underspecified, what the sender's worked example doesn't exercise. - -Output: a short summary of the thinking and a recommendation (do it / do it with named changes / file / reject). For shared-asset and convention changes the recommendation is surfaced to Craig for approval before applying; for ordinary tasks and files it feeds the act-vs-file and no-approvals-execute decision (=monitor-inbox.org=). - -** In a no-approvals session: shared-asset changes defer and stage - -Shared-asset and convention changes still don't self-apply when Craig has put the session in no-approvals mode — they need his decision, so they fail the *solo* test in monitor-inbox's executing-in-no-approvals criteria. Ordinary tasks and files that pass the review and are quick + solo execute under that criteria instead; this defer-and-stage path is for the shared-asset and convention changes that don't qualify. Run the review, prepare the edits in =working/<task-slug>/= (a patch file or the worked-out diff), file a =[#B]= VERIFY carrying the decision package, and reply to the sender that it's parked. The sender's local stopgap (per =cross-project.md='s propagation process) means the delay costs nothing — the canonical update is about durability, not speed. - -Wording-only fixes — no consuming project acts differently — may proceed even then, logged in the session log. - -The VERIFY shape (top-level, =[#B]= so startup's A/B surfacing catches it; no =SCHEDULED= unless the proposal names a real deadline): - -#+begin_example -** VERIFY [#B] Parked: <proposal topic> (from <sender>) -What arrived: <one line — what the handoff proposes>. -Recommendation: <accept as-is / accept with changes / reject> — <2-3 line -skeptical-review summary: what's right, what to change, what was checked>. -Prepared diff: [[file:working/<slug>/proposed.diff]] — apply is mechanical on -your go. -Say "approve the parked <topic>" (or adjust / reject) and it gets applied. -#+end_example - -The full question-battery answers live in the session log and the =working/= dir, not the task body — the body carries the conclusion, with the trail one link away. - -* 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. *Run the Skeptical Review* (section above) on the item before classifying — the core pass on every accepted task and file, plus the cross-project battery when it proposes a shared-asset or convention change. Its summary + recommendation rides along to Phase C; in a no-approvals session it gates whether the item self-applies (quick + solo + agreed, per =monitor-inbox.org=) or, for shared-asset and convention changes, defers and stages. -5. *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. -6. *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 items that went through the Skeptical Review, the surfaced disposition includes its summary + recommendation, and approval here is what authorizes the apply. In a no-approvals session those items are reported as parked (the =[#B]= VERIFY) rather than surfaced for live approval. - -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. - -** Park (Skeptical Review in a no-approvals session) - -Move the proposal file into =working/<task-slug>/= alongside the prepared diff, file the =[#B]= VERIFY per the Skeptical Review section, reply to the sender that it's parked for Craig's review, and delete the inbox file. On Craig's approval the apply is mechanical: apply the prepared edits, run the normal verify-and-publish flow, close the parked =**= VERIFY per =todo-format.md= (a top-level VERIFY resolves to =DONE= + =CLOSED:=, not a dated header), and send the sender the acceptance reply. On rejection, the reject-from-another-project flow above runs unchanged. - -* 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. -9. *Applying a shared-asset change proposal without the Skeptical Review.* The value gate alone asks whether to take the change, never whether the change is right, complete, or as simple as it should be. A proposal that's clear and bounded can still carry a design gap — the review is where that surfaces, before the change syncs to every consuming project. (Worked example: the 2026-06-12 spec-decisions handoff was applied as-is and the after-the-fact review surfaced a lost state, a vacuous gate pass, and an enhancement — all catchable up front.) - -* 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. |
