diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-12 20:04:05 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-12 20:04:05 -0500 |
| commit | 19829305721a327d07b6fe5b6dfba5bf34c8ed37 (patch) | |
| tree | 436a86299d8b88cde7c0fda56e034c38665fc478 | |
| parent | 4fa8fd739a09e4ddd424e434fe174e3180d2f233 (diff) | |
| download | rulesets-19829305721a327d07b6fe5b6dfba5bf34c8ed37.tar.gz rulesets-19829305721a327d07b6fe5b6dfba5bf34c8ed37.zip | |
feat(workflows): skeptical review gate for inbox change proposals
The value gate asks whether to take an inbox item, never whether the proposed change is right. process-inbox gains a Skeptical Review for proposals that change shared assets: a written question battery (fit for all consumers, conflicts elsewhere, effect on common activities, enhancement, simplification, plus at least three change-specific questions), ending in a summary and recommendation Craig approves before the change lands. In a no-approvals session, behavior-changing proposals park instead of self-applying: prepared diff in working/, a [#B] VERIFY carrying the decision package, a reply to the sender. Wording-only fixes proceed, logged.
monitor-inbox's act-vs-file rule and protocols.org's act-now line gain the matching exception so all three statements of the rule agree. protocols.org's tables picked up the org-table-standard reflow in the same pass.
The motivating case is today's spec-decisions handoff. I applied it as-is, and the after-the-fact review surfaced a lost state and a vacuous gate pass the battery would have caught up front.
| -rw-r--r-- | .ai/protocols.org | 54 | ||||
| -rw-r--r-- | .ai/workflows/monitor-inbox.org | 2 | ||||
| -rw-r--r-- | .ai/workflows/process-inbox.org | 47 | ||||
| -rw-r--r-- | claude-templates/.ai/protocols.org | 54 | ||||
| -rw-r--r-- | claude-templates/.ai/workflows/monitor-inbox.org | 2 | ||||
| -rw-r--r-- | claude-templates/.ai/workflows/process-inbox.org | 47 |
6 files changed, 162 insertions, 44 deletions
diff --git a/.ai/protocols.org b/.ai/protocols.org index 3fc7104..6b1d873 100644 --- a/.ai/protocols.org +++ b/.ai/protocols.org @@ -34,17 +34,26 @@ Every project using this template has an =.ai/= directory for Claude tooling and Every file and directory has a defined purpose: -| Item | Purpose | -|------+---------| -| =protocols.org= | Single entry point — behavioral instructions + directory map | -| =notes.org= | Project state: context, active reminders, pending decisions | -| =session-context.org= | Live session state (exists only during active sessions); renamed on wrap-up | -| =sessions/= | Archived session files (one per session) — =YYYY-MM-DD-HH-MM-description.org= | -| =workflows/= | Template workflows (synced from claude-templates, never edit in project) | -| =project-workflows/= | Project-specific workflows (never touched by sync) | -| =scripts/= | Template scripts (synced from claude-templates, never edit in project) | -| =project-scripts/= | Project-specific scripts (never touched by sync; mirrors =project-workflows/=) | -| =someday-maybe.org= | Project ideas backlog | +| Item | Purpose | +|-----------------------+--------------------------------------------------------------------------------| +| =protocols.org= | Single entry point — behavioral instructions + directory map | +|-----------------------+--------------------------------------------------------------------------------| +| =notes.org= | Project state: context, active reminders, pending decisions | +|-----------------------+--------------------------------------------------------------------------------| +| =session-context.org= | Live session state (exists only during active sessions); renamed on wrap-up | +|-----------------------+--------------------------------------------------------------------------------| +| =sessions/= | Archived session files (one per session) — =YYYY-MM-DD-HH-MM-description.org= | +|-----------------------+--------------------------------------------------------------------------------| +| =workflows/= | Template workflows (synced from claude-templates, never edit in project) | +|-----------------------+--------------------------------------------------------------------------------| +| =project-workflows/= | Project-specific workflows (never touched by sync) | +|-----------------------+--------------------------------------------------------------------------------| +| =scripts/= | Template scripts (synced from claude-templates, never edit in project) | +|-----------------------+--------------------------------------------------------------------------------| +| =project-scripts/= | Project-specific scripts (never touched by sync; mirrors =project-workflows/=) | +|-----------------------+--------------------------------------------------------------------------------| +| =someday-maybe.org= | Project ideas backlog | +|-----------------------+--------------------------------------------------------------------------------| ** =docs/= (visible, real project documentation) @@ -188,7 +197,7 @@ Check =inbox/= at every task boundary (after finishing a unit of work, before re .ai/scripts/inbox-status -q #+end_src -Exit 1 means handoffs are pending — process them per =process-inbox.org=. For each accepted handoff, the act-vs-file rule: *act now* when it's clear, bounded, low-risk, in-scope, and cheaper than deferring — just do it, no asking; *file* otherwise — ask first, with filing as option 1 and "do it now" as option 2; *ask* if unsure. Always reply to a handoff's sender (confirm on accept, the why on reject). Full process, the reply discipline, and the opt-in background-monitor =/loop= recipe live in =monitor-inbox.org=. +Exit 1 means handoffs are pending — process them per =process-inbox.org=. For each accepted handoff, the act-vs-file rule: *act now* when it's clear, bounded, low-risk, in-scope, and cheaper than deferring — just do it, no asking; *file* otherwise — ask first, with filing as option 1 and "do it now" as option 2; *ask* if unsure. Exception: a proposal to change a shared asset (template workflow, rule, skill, synced script) or a substantive convention never silently acts now — it goes through process-inbox's Skeptical Review and its approval (or park) step. Always reply to a handoff's sender (confirm on accept, the why on reject). Full process, the reply discipline, and the opt-in background-monitor =/loop= recipe live in =monitor-inbox.org=. ** Recursive Reads — Honor =.aiignore= @@ -240,10 +249,12 @@ For tool recipes, authentication details, and credentials, see [[file:references Craig has two GPG key pairs configured: -| Email | Key ID | Purpose | -|-------+--------+---------| -| =c@cjennings.net= | =3388FB17E147A563558F2CEC0E56F0A5B832F070= | Default key | +| Email | Key ID | Purpose | +|---------------------------------+--------------------------------------------+----------------| +| =c@cjennings.net= | =3388FB17E147A563558F2CEC0E56F0A5B832F070= | Default key | +|---------------------------------+--------------------------------------------+----------------| | =craigmartinjennings@gmail.com= | =1A1F6932A25357793FB2B4C51C4D081632A5CDA7= | Gmail identity | +|---------------------------------+--------------------------------------------+----------------| Both are RSA 4096-bit, passphrase-protected, no expiry. @@ -283,11 +294,14 @@ stamping it. Craig has three mail accounts. *Default to cmail for personal / non-work email* — reach for it unless the message is work-related. -| Account | Address | Use for | -|---------+---------+---------| -| =cmail= | =c@cjennings.net= (Proton Bridge) | *Default.* Personal / non-work mail. | -| =dmail= | =craig.jennings@deepsat.com= (Gmail) | Work mail. | -| =gmail= | =craigmartinjennings@gmail.com= | Third account, rarely the right one. | +| Account | Address | Use for | +|---------+--------------------------------------+--------------------------------------| +| =cmail= | =c@cjennings.net= (Proton Bridge) | *Default.* Personal / non-work mail. | +|---------+--------------------------------------+--------------------------------------| +| =dmail= | =craig.jennings@deepsat.com= (Gmail) | Work mail. | +|---------+--------------------------------------+--------------------------------------| +| =gmail= | =craigmartinjennings@gmail.com= | Third account, rarely the right one. | +|---------+--------------------------------------+--------------------------------------| *The tool is =cmail-action send=* (symlinked into =~/.local/bin=, on PATH from any project). Don't hand-roll MIME or pipe raw messages through =msmtp= — the script builds the message, threading, and attachments for you. diff --git a/.ai/workflows/monitor-inbox.org b/.ai/workflows/monitor-inbox.org index dd545d9..1639f3b 100644 --- a/.ai/workflows/monitor-inbox.org +++ b/.ai/workflows/monitor-inbox.org @@ -52,6 +52,8 @@ Every accepted handoff (one that clears process-inbox's value gate) is then eith 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. diff --git a/.ai/workflows/process-inbox.org b/.ai/workflows/process-inbox.org index c6b3f79..86df4c2 100644 --- a/.ai/workflows/process-inbox.org +++ b/.ai/workflows/process-inbox.org @@ -33,6 +33,41 @@ Every inbox item passes through three questions. One *yes* is enough to accept. 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 (change proposals) + +The value gate decides whether an item is worth taking. This review decides whether the proposed change is *right*. It applies to any item proposing a change to shared assets — template workflows, rules, skills, scripts, anything synced to consuming projects — and to any substantive convention change. FYIs, replies, and routine task filings skip it. + +Approach the file with curiosity and skepticism. It arrived from one project's context; you're evaluating it for all of them. Work through, in writing: + +1. Does this make sense for *all* consuming projects, or just the sender's situation? +2. Does it conflict with any existing instruction — workflows, skills, rules, protocols, CLAUDE.md? +3. How does it change a common activity Craig performs — better, worse, or differently than the sender assumed? +4. Can it be enhanced to be more effective than as proposed? +5. Should it be simpler? +6. Plus at least three more questions specific to this change — e.g. what breaks for artifacts already using the old shape, what tooling interacts with it, what's underspecified, what does the sender's worked example not exercise? + +Output: a short summary of the thinking and a recommendation (accept as-is / accept with named changes / reject), surfaced to Craig for approval before applying. + +** In a no-approvals session: defer and stage + +Behavior-changing proposals still don't self-apply when Craig has put the session in no-approvals mode. 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: @@ -65,11 +100,12 @@ 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:* +4. *Run the Skeptical Review* (section above) on any accepted item that proposes a shared-asset or convention change, before classifying. Its summary + recommendation rides along to Phase C; in a no-approvals session its defer-and-stage path replaces implement-now for behavior-changing proposals. +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. -5. *Within reject, classify by source:* +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. @@ -104,6 +140,8 @@ Disposition recommendation: <implement / fold into <TODO> / file [#X] :tags: / r 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 @@ -146,6 +184,10 @@ Just delete. No notification. 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, rewrite the VERIFY to a dated log entry per =todo-format.md=, 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. @@ -164,6 +206,7 @@ Stamp =:LAST_INBOX_PROCESS:= in =notes.org='s *Workflow State* section if it exi 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 diff --git a/claude-templates/.ai/protocols.org b/claude-templates/.ai/protocols.org index 3fc7104..6b1d873 100644 --- a/claude-templates/.ai/protocols.org +++ b/claude-templates/.ai/protocols.org @@ -34,17 +34,26 @@ Every project using this template has an =.ai/= directory for Claude tooling and Every file and directory has a defined purpose: -| Item | Purpose | -|------+---------| -| =protocols.org= | Single entry point — behavioral instructions + directory map | -| =notes.org= | Project state: context, active reminders, pending decisions | -| =session-context.org= | Live session state (exists only during active sessions); renamed on wrap-up | -| =sessions/= | Archived session files (one per session) — =YYYY-MM-DD-HH-MM-description.org= | -| =workflows/= | Template workflows (synced from claude-templates, never edit in project) | -| =project-workflows/= | Project-specific workflows (never touched by sync) | -| =scripts/= | Template scripts (synced from claude-templates, never edit in project) | -| =project-scripts/= | Project-specific scripts (never touched by sync; mirrors =project-workflows/=) | -| =someday-maybe.org= | Project ideas backlog | +| Item | Purpose | +|-----------------------+--------------------------------------------------------------------------------| +| =protocols.org= | Single entry point — behavioral instructions + directory map | +|-----------------------+--------------------------------------------------------------------------------| +| =notes.org= | Project state: context, active reminders, pending decisions | +|-----------------------+--------------------------------------------------------------------------------| +| =session-context.org= | Live session state (exists only during active sessions); renamed on wrap-up | +|-----------------------+--------------------------------------------------------------------------------| +| =sessions/= | Archived session files (one per session) — =YYYY-MM-DD-HH-MM-description.org= | +|-----------------------+--------------------------------------------------------------------------------| +| =workflows/= | Template workflows (synced from claude-templates, never edit in project) | +|-----------------------+--------------------------------------------------------------------------------| +| =project-workflows/= | Project-specific workflows (never touched by sync) | +|-----------------------+--------------------------------------------------------------------------------| +| =scripts/= | Template scripts (synced from claude-templates, never edit in project) | +|-----------------------+--------------------------------------------------------------------------------| +| =project-scripts/= | Project-specific scripts (never touched by sync; mirrors =project-workflows/=) | +|-----------------------+--------------------------------------------------------------------------------| +| =someday-maybe.org= | Project ideas backlog | +|-----------------------+--------------------------------------------------------------------------------| ** =docs/= (visible, real project documentation) @@ -188,7 +197,7 @@ Check =inbox/= at every task boundary (after finishing a unit of work, before re .ai/scripts/inbox-status -q #+end_src -Exit 1 means handoffs are pending — process them per =process-inbox.org=. For each accepted handoff, the act-vs-file rule: *act now* when it's clear, bounded, low-risk, in-scope, and cheaper than deferring — just do it, no asking; *file* otherwise — ask first, with filing as option 1 and "do it now" as option 2; *ask* if unsure. Always reply to a handoff's sender (confirm on accept, the why on reject). Full process, the reply discipline, and the opt-in background-monitor =/loop= recipe live in =monitor-inbox.org=. +Exit 1 means handoffs are pending — process them per =process-inbox.org=. For each accepted handoff, the act-vs-file rule: *act now* when it's clear, bounded, low-risk, in-scope, and cheaper than deferring — just do it, no asking; *file* otherwise — ask first, with filing as option 1 and "do it now" as option 2; *ask* if unsure. Exception: a proposal to change a shared asset (template workflow, rule, skill, synced script) or a substantive convention never silently acts now — it goes through process-inbox's Skeptical Review and its approval (or park) step. Always reply to a handoff's sender (confirm on accept, the why on reject). Full process, the reply discipline, and the opt-in background-monitor =/loop= recipe live in =monitor-inbox.org=. ** Recursive Reads — Honor =.aiignore= @@ -240,10 +249,12 @@ For tool recipes, authentication details, and credentials, see [[file:references Craig has two GPG key pairs configured: -| Email | Key ID | Purpose | -|-------+--------+---------| -| =c@cjennings.net= | =3388FB17E147A563558F2CEC0E56F0A5B832F070= | Default key | +| Email | Key ID | Purpose | +|---------------------------------+--------------------------------------------+----------------| +| =c@cjennings.net= | =3388FB17E147A563558F2CEC0E56F0A5B832F070= | Default key | +|---------------------------------+--------------------------------------------+----------------| | =craigmartinjennings@gmail.com= | =1A1F6932A25357793FB2B4C51C4D081632A5CDA7= | Gmail identity | +|---------------------------------+--------------------------------------------+----------------| Both are RSA 4096-bit, passphrase-protected, no expiry. @@ -283,11 +294,14 @@ stamping it. Craig has three mail accounts. *Default to cmail for personal / non-work email* — reach for it unless the message is work-related. -| Account | Address | Use for | -|---------+---------+---------| -| =cmail= | =c@cjennings.net= (Proton Bridge) | *Default.* Personal / non-work mail. | -| =dmail= | =craig.jennings@deepsat.com= (Gmail) | Work mail. | -| =gmail= | =craigmartinjennings@gmail.com= | Third account, rarely the right one. | +| Account | Address | Use for | +|---------+--------------------------------------+--------------------------------------| +| =cmail= | =c@cjennings.net= (Proton Bridge) | *Default.* Personal / non-work mail. | +|---------+--------------------------------------+--------------------------------------| +| =dmail= | =craig.jennings@deepsat.com= (Gmail) | Work mail. | +|---------+--------------------------------------+--------------------------------------| +| =gmail= | =craigmartinjennings@gmail.com= | Third account, rarely the right one. | +|---------+--------------------------------------+--------------------------------------| *The tool is =cmail-action send=* (symlinked into =~/.local/bin=, on PATH from any project). Don't hand-roll MIME or pipe raw messages through =msmtp= — the script builds the message, threading, and attachments for you. diff --git a/claude-templates/.ai/workflows/monitor-inbox.org b/claude-templates/.ai/workflows/monitor-inbox.org index dd545d9..1639f3b 100644 --- a/claude-templates/.ai/workflows/monitor-inbox.org +++ b/claude-templates/.ai/workflows/monitor-inbox.org @@ -52,6 +52,8 @@ Every accepted handoff (one that clears process-inbox's value gate) is then eith 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. diff --git a/claude-templates/.ai/workflows/process-inbox.org b/claude-templates/.ai/workflows/process-inbox.org index c6b3f79..86df4c2 100644 --- a/claude-templates/.ai/workflows/process-inbox.org +++ b/claude-templates/.ai/workflows/process-inbox.org @@ -33,6 +33,41 @@ Every inbox item passes through three questions. One *yes* is enough to accept. 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 (change proposals) + +The value gate decides whether an item is worth taking. This review decides whether the proposed change is *right*. It applies to any item proposing a change to shared assets — template workflows, rules, skills, scripts, anything synced to consuming projects — and to any substantive convention change. FYIs, replies, and routine task filings skip it. + +Approach the file with curiosity and skepticism. It arrived from one project's context; you're evaluating it for all of them. Work through, in writing: + +1. Does this make sense for *all* consuming projects, or just the sender's situation? +2. Does it conflict with any existing instruction — workflows, skills, rules, protocols, CLAUDE.md? +3. How does it change a common activity Craig performs — better, worse, or differently than the sender assumed? +4. Can it be enhanced to be more effective than as proposed? +5. Should it be simpler? +6. Plus at least three more questions specific to this change — e.g. what breaks for artifacts already using the old shape, what tooling interacts with it, what's underspecified, what does the sender's worked example not exercise? + +Output: a short summary of the thinking and a recommendation (accept as-is / accept with named changes / reject), surfaced to Craig for approval before applying. + +** In a no-approvals session: defer and stage + +Behavior-changing proposals still don't self-apply when Craig has put the session in no-approvals mode. 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: @@ -65,11 +100,12 @@ 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:* +4. *Run the Skeptical Review* (section above) on any accepted item that proposes a shared-asset or convention change, before classifying. Its summary + recommendation rides along to Phase C; in a no-approvals session its defer-and-stage path replaces implement-now for behavior-changing proposals. +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. -5. *Within reject, classify by source:* +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. @@ -104,6 +140,8 @@ Disposition recommendation: <implement / fold into <TODO> / file [#X] :tags: / r 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 @@ -146,6 +184,10 @@ Just delete. No notification. 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, rewrite the VERIFY to a dated log entry per =todo-format.md=, 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. @@ -164,6 +206,7 @@ Stamp =:LAST_INBOX_PROCESS:= in =notes.org='s *Workflow State* section if it exi 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 |
