diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-28 08:18:10 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-28 08:18:10 -0500 |
| commit | db7f82711978da5e7f152297942854c7b753f480 (patch) | |
| tree | 68ea4ce52cbb278114acf0243fe7397d2f1d6efc /inbox | |
| parent | ee7049aaa62d0c38e83f20c0b3796e5eded4ca23 (diff) | |
| download | rulesets-db7f82711978da5e7f152297942854c7b753f480.tar.gz rulesets-db7f82711978da5e7f152297942854c7b753f480.zip | |
chore(audit): task-audit pass + pearl intake from 2026-05-28 morning
All 16 open tasks bucketed and updated. 14 received autonomous Phase C
edits (13 type-tag additions per the new scheme plus #15's body refresh
for the accumulating pearl signal). Phase D adjudicated two priority
bumps and the morning's inbox spillover. Phase E stamped :LAST_AUDIT:
in notes.org Workflow State.
Autonomous Phase C:
- Tagged tasks 1-11 and 13-14 with their type tag (:feature:, :chore:,
:spec:), bumped LAST_REVIEWED to 2026-05-28. Tasks 12, 15, 16 already
carried type tags.
- Refreshed task #15 body to reference the four pearl pattern-catalog
notes now in docs/design/ (six worked patterns total).
Phase D adjudication:
- #15 (cross-project pattern catalog) bumped [#C] to [#B]. Pearl shipped
6 worked examples plus a synthesizing principle and is asking for
spec-review iterations. Design questions still open but evidence is
past the tipping point.
- Filed new [#B] :feature: TODO for the codex Phase 1 race-fix
(AI_AGENT_ID + session-context.d/<id>.org), lifted from the broader
runtime spec (#16). Phase 1 alone is low-risk and fixes a real
correctness issue under simultaneous agents.
Pearl intake (4 inbox files from this morning):
- Moved 0155 (patterns 4-5) and 0303 (pattern 6) into docs/design/
alongside the prior two pattern-catalog notes. Referenced from #15.
- Filed new [#C] :chore:quick:solo: TODO for pearl 0138's
--archive-done sweep at the start of open-tasks.org Phase A.
- Filed new [#C] :feature:solo: TODO for pearl 0226's spec-review.org
Phase 6 implementation-task enumeration.
- Deleted 0124. Already implemented this session as the audit-warranted
pre-step plus the LAST_AUDIT stamp now live in the workflow files.
Diffstat (limited to 'inbox')
6 files changed, 98 insertions, 325 deletions
diff --git a/inbox/2026-05-28-0124-from-.emacs.d-suggestion-whats-next-auto-considers-task-audit.org b/inbox/2026-05-28-0124-from-.emacs.d-suggestion-whats-next-auto-considers-task-audit.org deleted file mode 100644 index 4e3e6fd..0000000 --- a/inbox/2026-05-28-0124-from-.emacs.d-suggestion-whats-next-auto-considers-task-audit.org +++ /dev/null @@ -1,86 +0,0 @@ -#+TITLE: Suggestion — what's-next should auto-consider task-audit and run when warranted -#+FROM: dotemacs (~/.emacs.d) -#+DATE: 2026-05-28 - -* Suggestion - -Extend =claude-templates/.ai/workflows/open-tasks.org= Next Mode with a pre-step: before producing the cascade + friction output, evaluate whether a =task-audit= is warranted and offer to run it first. The user shouldn't have to remember to schedule audits — they get triggered by the workflow when needed. - -* Why - -Task-audit is the "is each task factually accurate?" workflow. Its value compounds with drift: as sessions land changes, as deadlines pass, as referenced files move, the open-task body content drifts out of sync with reality. Today the user has to remember to invoke =task-audit= explicitly. In practice that means audits happen rarely and the open-task set accumulates stale claims. - -The =task-review= workflow already runs daily as a habit. The =task-audit= workflow runs roughly never. Coupling audit to "what's next" closes that gap — every time the user asks the system to recommend work, the system checks whether the recommendation is being made over stale facts and offers to clean up first. - -* The criteria for "warranted" - -Hybrid: temporal threshold OR state-signal detection. Either trips it. - -** Temporal threshold - -Track =:LAST_AUDIT:= in =notes.org= under a new "Workflow State" section (or, alternately, as a single-line marker like =# LAST_AUDIT: YYYY-MM-DD= at the bottom of =notes.org=). If absent, treat as "never run." If older than 14 days, the threshold trips. - -The threshold value (14 days) is a starting point — projects with high churn could tune it down, low-churn projects up. Lives as a per-project knob in =notes.org=. - -** State-signal scan - -During Phase A's existing snapshot, check these cheap signals: - -1. *Reminder-vs-task mismatch.* Active Reminder names a task or completion target that doesn't appear in =todo.org= (or vice versa: =todo.org= names a reminder that isn't in =notes.org='s Active Reminders). -2. *Passed scheduled date.* A task with a =SCHEDULED:= or =DEADLINE:= date earlier than today, still =TODO= or =DOING=, no completion log. -3. *"Waiting on X" matches a completed X.* Task body contains a phrase like "waiting on", "after X ships", "blocked by"; the recent session summaries (already in the snapshot) log the named X as shipped. -4. *Reference to deleted artifact.* A task body's =file:= link points to a path that doesn't exist (use a single existence check per linked path). -5. *Sub-task DONE coverage.* A task with many sub-tasks where >75% are DONE/CANCELLED but the parent is still =TODO= or =DOING= — a likely promotion candidate. - -Any one signal trips the audit-warranted flag. Signals 1–3 are cheap. Signal 4 needs filesystem access (still cheap per-task). Signal 5 is a counting pass. - -** Combined - -Audit warranted if (temporal threshold tripped) OR (any state signal tripped). - -* Proposed Phase A addition - -Add to the Phase A parallel batch (after the existing 4 reads): - -5. Read the =:LAST_AUDIT:= marker from =notes.org= (or note its absence). - -* Proposed new section: Phase A.1 — Audit warranted? - -Between Phase A and Phase B, evaluate the warranted check from the snapshot. If tripped, surface to the user with numbered options: - -#+begin_example -Task-audit looks worth running before this recommendation: -- Temporal: <N> days since last audit (threshold 14) -- Signal: <specific finding, e.g. "L46 reminder names 'fix X' but no task matches"> - -1. Run task-audit first — fixes the facts, then I'll come back to next-task -2. Skip the audit — proceed straight to what's next -3. Run audit but only the autonomous half (factual updates) — defer the judgment calls to a later session -#+end_example - -If not tripped, proceed silently to Phase B. - -* Refreshing :LAST_AUDIT: - -When =task-audit= runs from anywhere, its Phase C should stamp =:LAST_AUDIT:= to today's date in =notes.org=. The trigger has to live in =task-audit.org= so it works for the manual invocation too, not just the chained-from-whats-next path. That's a one-line addition to that workflow's Phase D close-out. - -* Implementation order - -Two coupled changes that should land together: - -1. =task-audit.org= Phase D — stamp =:LAST_AUDIT:= on completion (date format =YYYY-MM-DD= for trivial parsing). -2. =open-tasks.org= — add the Phase A read, the new Phase A.1 evaluate-warranted block, and a "Common Mistakes" entry "Running the cascade over stale facts — always evaluate audit-warranted first; let the user override." - -If only one of the two lands, the feature is broken — the stamp wouldn't get set without the audit edit; the audit-warranted check would fail without the read. Land them as a pair. - -* Open questions - -- Storage location for =:LAST_AUDIT:= — a top-of-notes.org property line, a dedicated "Workflow State" subsection in notes.org, or a sibling =.ai/workflow-state.org= file. (The sibling file is cleanest if more workflow-state markers accumulate; notes.org is fine for one or two.) -- Threshold value — 14 days is a defensible default but should be a per-project knob. Naming the knob: a top-of-notes.org line =# AUDIT_THRESHOLD_DAYS: 14= alongside the marker? -- Should the audit run automatically (no prompt) when both signals AND threshold trip? The recommendation-first convention argues for prompting with item 1 = "yes run it" rather than silent auto-run, since "what's next" is interactive anyway. - -* Source - -Drafted from the dotemacs session 2026-05-28. The user's framing: "I won't really ever have to think about the task-audit workflow." This suggestion answers that — by hooking it to the workflow the user already invokes. - -References the prior two rulesets suggestions (=2026-05-28-0014-from-.emacs.d-...= for recommendation-first option ordering, and =2026-05-28-0117-from-.emacs.d-...= for the open-tasks.org hybrid output shape). The auto-audit pre-step is the third leg of the same triple — together they make "what's next" the single point of entry for task-level work. diff --git a/inbox/2026-05-28-0138-from-pearl-rulesets-open-tasks-archive-done.org b/inbox/2026-05-28-0138-from-pearl-rulesets-open-tasks-archive-done.org deleted file mode 100644 index fd6687b..0000000 --- a/inbox/2026-05-28-0138-from-pearl-rulesets-open-tasks-archive-done.org +++ /dev/null @@ -1,29 +0,0 @@ -#+TITLE: open-tasks workflow should run --archive-done before reading -#+DATE: [2026-05-28 Thu] -#+SOURCE: pearl session 2026-05-28 - -* The gap - -=workflows/open-tasks.org= (the "what's next" / "list open tasks" workflow that merged in the older =whats-next.org=) reads =todo.org='s =* Project Open Work= section in Phase A and skips =* Project Resolved=. That's correct in principle, but in practice a level-2 task that completed during the session sits as =** DONE= under =Open Work= until something archives it. The cleanup tool's =--archive-done= sweep is what moves it to =Resolved=, and only =workflows/clean-todo.org= and the wrap-up workflow currently run it. - -The consequence: between cleanups, =open-tasks.org= can surface a freshly-DONE task as a "what's next" candidate. The reconcile phase doesn't filter on TODO state. In a session where Craig shipped a few things and immediately asks "what's next," he gets recommendations that include work he just finished. - -* Proposed fix - -Add an =--archive-done= sweep as the first step of =open-tasks.org='s Phase A, before the parallel reads. One line: - -#+begin_src bash -emacs --batch -q -l .ai/scripts/todo-cleanup.el --archive-done todo.org -#+end_src - -Then Phase A's read of =todo.org= sees a clean Open Work section and the reconciliation works against current state. - -The cost is a few hundred milliseconds at the start of every "what's next" invocation. The win is recommendations that never include DONE work. - -* Optional refinement - -If the workflow ever runs in a context where Craig actively does *not* want write side effects (a read-only dry run, a presentation mode), gate the sweep behind a check. The default invocation should still archive — the dry-run case is the exception. - -* Triggered by - -2026-05-28 pearl session, after marking several VERIFY tests DONE inline during a verify walk-through. Craig flagged that the next "what's next" would see those still in Open Work until the next cleanup. diff --git a/inbox/2026-05-28-0155-from-pearl-rulesets-followup-prompts-ux.org b/inbox/2026-05-28-0155-from-pearl-rulesets-followup-prompts-ux.org deleted file mode 100644 index cc2cb77..0000000 --- a/inbox/2026-05-28-0155-from-pearl-rulesets-followup-prompts-ux.org +++ /dev/null @@ -1,69 +0,0 @@ -#+TITLE: Pattern catalog — two more worked examples from pearl prompts -#+DATE: [2026-05-28 Thu] -#+SOURCE: pearl session 2026-05-28, follow-up to earlier UI-patterns notes - -* Two more pattern examples landed today - -Both shipped in pearl as commit =505e707= on 2026-05-28. They sharpen earlier catalog candidates rather than introducing a new direction. - -* Pattern 4: "The prompt label should match what the prompt does" - -** Before - -Pearl's filter-builder prompts and saved-query prompts both carried the same sentinel string at the top: =[ None. ]=. The label was uniform but the *behavior* was two different things: - -- For filter dimensions (team, state, project, labels, assignee), picking the sentinel meant "no constraint on this dimension." Every value matches. That's *any*, not *none*. -- For the saved-query pick prompts (delete, run), picking the sentinel meant "don't act on anything." That's *cancel*, not *none* or *any*. - -Craig caught this on 2026-05-28 during verify: "when does the choice presented in completing read say 'none' when the choice actually means 'any'? Find all these instances and a way to correct them." - -** After - -Two distinct sentinel constants with labels that match their behavior: - -- =[ Any. ]= for filter dimensions -- =[ Cancel. ]= for pick-an-existing-thing prompts - -A generic =pearl--with-sentinel SENTINEL CANDIDATES= helper lets each call site pick the label that fits. The predicate that recognizes opt-out (=pearl--filter-sentinel-value-p=) matches either sentinel or empty/nil so the downstream logic is uniform. - -** Why for the catalog - -This is the "no hidden affordances" pattern from the earlier note ([[file:2026-05-28-0003-from-pearl-rulesets-followup-no-empty-input.org]]) sharpened with a second rule: *if the affordance is visible, its label has to match what picking it does*. Visibility without accuracy is its own problem. A label that says "none" when the behavior is "any" is no better than an invisible empty-input idiom — both leave the user holding the wrong model. - -Catalog shape suggestion: this is the same principle as Pattern 3, in a follow-up form. Either a single entry that captures both halves (visible + accurate) or two cross-linked entries. - -* Pattern 5: "Default the most-common choice, not always 'yes'" - -** Refinement of an earlier idea - -In yesterday's discussion of yes/no prompts, the working principle was "default the choice to 'yes' so RET takes it." Craig pushed back today: "what I'm after is having the most common or preferred option be the one on top, not just 'yes' all the time." - -** What that looks like in code - -A new =pearl--read-yes-no PROMPT &optional DEFAULT= helper takes the default as an argument. The candidate list is ordered with the default first so the most-common choice is what the user sees at the top, the framework highlights it, and RET takes it without typing. - -For pearl's three non-destructive yes/no prompts (open-issues-only, save-filter-locally, save-N-fields-across-M-issues), the default happens to be "yes" in each case because each is a do-the-thing-the-user-asked confirmation. But the helper signature makes the *next* prompt where "no" is more common a one-arg change, not a special case. - -** Companion rule: friction proportional to consequence - -The destructive yes/no prompts (delete issue, delete saved query, delete comment) deliberately stay as =yes-or-no-p=. Typing "yes" is a safety feature there, not friction to remove. The catalog entry should name this companion rule explicitly so the principle doesn't read as "always default-yes." - -** Why for the catalog - -This is a refinement of Pattern 3 ("no empty input as meaningful") rather than a new pattern. The cleaner phrasing is something like *the prompt's default is the choice the user most often wants, and the level of friction is proportional to the cost of the choice*. Two halves, one principle. - -* Cumulative shape - -After today's work, the catalog has five candidate patterns from pearl, all converging on the same underlying principle: - -1. One-prompt picker with typed prefix (from 2026-05-27) -2. Transient state-buttons (from 2026-05-27, Craig's external reference) -3. No empty input as meaningful (from 2026-05-28, earlier today) -4. The prompt label matches what the prompt does (today's first refinement) -5. Default the most-common choice, with friction proportional to consequence (today's second refinement) - -Patterns 1, 3, 4, 5 are arguably one principle in four shapes: *the choices the user has should all be on-screen, accurately labeled, ordered by what they'll most often want, with friction sized to the cost of being wrong*. Worth thinking about whether the catalog wants one entry that captures all four with worked examples, or four separate entries that cross-link. The single-principle-multiple-shapes form may scan more cleanly once five-plus patterns have accumulated. - -* Standing by - -Same as the earlier notes: spec-reviews welcome when the rulesets discussion produces a concrete shape. diff --git a/inbox/2026-05-28-0226-from-pearl-rulesets-spec-review-implementation.org b/inbox/2026-05-28-0226-from-pearl-rulesets-spec-review-implementation.org deleted file mode 100644 index 5af3502..0000000 --- a/inbox/2026-05-28-0226-from-pearl-rulesets-spec-review-implementation.org +++ /dev/null @@ -1,53 +0,0 @@ -#+TITLE: spec-review.org should enumerate implementation tasks for todo.org -#+DATE: [2026-05-28 Thu] -#+SOURCE: pearl session 2026-05-28 - -* The gap - -=workflows/spec-review.org= Phase 6 says "log deferred work to =todo.org=: v1 implementation = [#B] ... vNext/someday = [#D]." That covers *deferred* items (vNext) and a passing mention of v1 implementation, but it doesn't ask the workflow to enumerate, in the review output, the *concrete tasks* that fully implementing and testing the spec would require. The result: a spec gets marked =Ready=, the reviewer hands off, and the next session has to re-derive the task breakdown from the spec text rather than reading a ready-made list. - -For specs that decompose cleanly into commits (which is most of them now that the =Implementation phases= convention from =issue-sources-spec.org= has spread), the breakdown is *already in the spec*. The workflow just needs to lift it into the review output in a form that drops straight into =todo.org=. - -* Proposed addition to Phase 6 - -After the existing "log deferred work to todo.org" sentence, add a structured step: - -#+begin_src org -,*** Step: Enumerate the implementation tasks - -Read the spec's =Implementation phases= section (or equivalent commit/phase breakdown). For each phase, produce a =[#B] TODO= entry as it would appear in =todo.org=, including: - -- Subject line (descriptive topic, kebab-case slug, conventional-commit style). -- Tags (=:feature:= / =:bug:= / =:refactor:= / =:test:= and any of =:quick:= / =:solo:= / =:discuss:= that apply). -- One-line body: what lands in this phase. -- Pointer back to the spec. - -Add a final =[#B] TODO= entry for the test surface that lands alongside the commits (unit tests, integration tests, manual-verify checklist). If the spec's =Acceptance criteria= section enumerates verifiable behaviors, mirror them as the manual-verify entries. - -Append the enumerated entries to the review file under a new heading: - -,* Implementation tasks (drop-in for todo.org) -The full list of todo.org entries that fully implementing and testing this spec would require. Copy-paste into =todo.org='s =* $Project Open Work= header. Each entry is independently shippable per the spec's commit decomposition. - -If the spec doesn't have an =Implementation phases= section, this step is the prompt to ask the author to add one before assigning =Ready=. A spec without a phase breakdown is hard to plan against and harder to review the implementation of. -#+end_src - -The step lives inside Phase 6 because it's part of "update tracking," but the output is sized to drop straight into =todo.org= — Craig (or the next agent) copy-pastes rather than re-deriving. The format mirrors =todo-format.md= (terse heading + body, tags on the heading line, no sentence-shaped headings). - -* Why this matters - -Three concrete wins: - -1. *Hand-off is one paste, not a re-read.* The reviewer already understands the spec well enough to assign a rubric. They're the right person to enumerate the work. Doing it in the review file means the spec-response author (or implementer) doesn't re-derive the breakdown from the spec narrative. - -2. *Forces a spec to be implementable in pieces.* If the reviewer can't write the implementation-tasks list, the spec doesn't have a clean phase decomposition. That's a spec-shape problem worth surfacing before =Ready=. The step is its own implementation-readiness check. - -3. *Closes the loop on =Acceptance criteria=.* Specs often have a numbered acceptance list and a separate commit decomposition. Mirroring the acceptance numbers as manual-verify task entries ensures every claim gets a check — the verify list isn't an afterthought. - -* Merge-with-pending note - -I noticed three uncommitted edits in =claude-templates/.ai/workflows/= (open-tasks, spec-response, spec-review) when I rsynced templates earlier today. If there's already a pending recommendation thread for =spec-review.org=, merge this addition with it rather than treating them as separate proposals. The change is additive (new step inside an existing phase, new review-file section), so it should compose with most other changes cleanly. - -* Triggered by - -2026-05-28 pearl session, while writing =docs/saved-query-sync-spec.org= and entering its sprint-review cycle. Craig: "update the spec review workflow such that it also lists all the actual tasks it would enter in todo.org to fully implement and test the functionality of the spec." Worked example landed at the bottom of =docs/saved-query-sync-spec.org= showing what the section looks like in practice. diff --git a/inbox/2026-05-28-0303-from-pearl-rulesets-followup-collapse-prompts.org b/inbox/2026-05-28-0303-from-pearl-rulesets-followup-collapse-prompts.org deleted file mode 100644 index bef4516..0000000 --- a/inbox/2026-05-28-0303-from-pearl-rulesets-followup-collapse-prompts.org +++ /dev/null @@ -1,88 +0,0 @@ -#+TITLE: Pattern catalog — collapse N orthogonal prompts into one enriched prompt -#+DATE: [2026-05-28 Thu] -#+SOURCE: pearl session 2026-05-28, third follow-up to UI-patterns thread - -* Pattern 6 (or refinement of 4): "Collapse N orthogonal prompts into one enriched prompt where each candidate is a complete end-state" - -Shipped as a design decision in =docs/saved-query-sync-spec.org= on 2026-05-28 during sprint review. Sharpens earlier catalog candidates rather than introducing a new direction. - -** The trigger - -Craig, while reviewing the spec's sync-saved-query-to-linear command: "have we informed the user if this choice is consequential in any way? this almost feels as if we can collapse two levels together by adding more information to each individual choice." - -The spec originally proposed two sequential prompts: -1. Team scope: =[ Personal. ]= / Engineering / Marketing / ... -2. Shared visibility: personal / shared - -Four orthogonal combinations the user had to mentally assemble: -- Personal scope + personal visibility = "just me, no team" -- Personal scope + shared visibility = doesn't quite make sense (no team to share with) -- Team scope + personal visibility = "team-scoped but only I see it" -- Team scope + shared visibility = "team-scoped and team-visible" (the typical sync intent) - -** The collapse - -One prompt where each candidate spells out the complete end-state: - -#+begin_example -Where does this view live? - [ Team: Engineering, visible to the team ] <- default when :team Engineering in filter - [ Personal, only I see it ] - [ Team: Engineering, only I see it ] - [ Team: Marketing, visible to the team ] - [ Team: Marketing, only I see it ] - ... - [ Cancel. ] -#+end_example - -Same logical surface (N teams × 2 visibility + 1 personal). One fewer modal moment. Meaningless combination (personal + shared) absent from the list. Default at the top per the existing most-common-on-top pattern. - -** What changed by the collapse - -- Two prompts went to one. Smaller stack of decisions to track. -- Each option is now self-explanatory. "Visible to the team" reads as the consequence, not the mechanism. -- The default conveys *what will happen*, not just *which radio button is selected*. -- The degenerate combination doesn't have to be defended against in code -- it's not in the candidate list. - -** Why for the catalog - -This is a third worked form of the principle that's emerging across the pearl catalog notes: - -#+begin_quote -The choices the user has should all be on screen, accurately labeled, ordered by what they'll most often want, with friction sized to the cost of being wrong. -#+end_quote - -Previous catalog candidates touch parts of it: -- Pattern 3 (no empty input as meaningful): visible choices, no hidden idioms. -- Pattern 4 (prompt label matches behavior): accurate labels. -- Pattern 5 (default the most-common choice): right ordering, with safety-proportional friction. - -This pattern (collapse N orthogonal prompts into one enriched prompt) is the *cross-product* form. When two or more prompts compose, each combination IS its own meaningful choice, and the user thinks about end-states, not dimensions. So show the cross-product, label each row with its end-state, and let the user pick destination rather than coordinates. - -** Applicability gate - -The collapse only works when the cross-product is small enough to scan (5-20 rows comfortably). For N=2 dimensions × M values, that's 2M to N×M rows depending on whether all combinations are meaningful. - -It doesn't work when: -- The cross-product is large (many teams, many statuses, many priorities -- the candidate list becomes a wall). -- Dimensions are independently and frequently re-set (the user wants to change one without re-picking the rest). -- One dimension is "free text" (not a small enumerable set). - -For those cases the sequential-prompts shape stays appropriate. - -** Cumulative shape after this entry - -The pearl catalog now has six worked candidates: - -1. One-prompt picker with typed prefix (2026-05-27) -2. Transient state-buttons (Craig's external reference; magit-transient) -3. No empty input as meaningful (2026-05-28) -4. The prompt label matches what the prompt does (2026-05-28) -5. Default the most-common choice; friction sized to consequence (2026-05-28) -6. Collapse N orthogonal prompts into one enriched prompt (this note, 2026-05-28) - -Patterns 1, 3, 4, 5, 6 are arguably one principle in five shapes. The catalog might want a single root entry (the principle stated once) with five cross-linked worked examples; or six tightly-cross-linked separate entries. The single-principle-multiple-shapes form scans more cleanly as the count grows; six independent entries fragments the underlying idea. - -* Standing by - -Spec reviews welcome when the rulesets discussion produces a concrete shape. Pearl's docs/saved-query-sync-spec.org now sits at =Ready=; implementation can start whenever Craig says. diff --git a/inbox/2026-05-28-0814-from-pearl-no-approvals.org b/inbox/2026-05-28-0814-from-pearl-no-approvals.org new file mode 100644 index 0000000..e61b69d --- /dev/null +++ b/inbox/2026-05-28-0814-from-pearl-no-approvals.org @@ -0,0 +1,98 @@ +#+TITLE: No-Approvals Mode +#+AUTHOR: Craig Jennings & Claude +#+DATE: 2026-05-28 + +* Heads-up from pearl (2026-05-28) + +Craig flagged that he plans to use a "no-approvals" mode and the rulesets project is already building one. He drafted this in pearl as a project-workflow (=.ai/project-workflows/no-approvals.org=) and asked that a copy come here so rulesets can compare with whatever is in flight there and take the best from both. + +Source path in pearl: =/home/cjennings/code/pearl/.ai/project-workflows/no-approvals.org=. + +Key points Craig dictated, in his own framing: +- Explicit way to signal there are no approval gates until he turns them back on. +- Don't stop at any approval gate. Finish each task fully, then start the next. Continue until a question arises or the next work item is unknown. +- Triggers he'll use: queuing several tasks in =todo.org= then "do all =:quick:solo:= with no-approval", or just "no-approval" / "no approvals" / "no need for approval gates" in a command. +- Engineering discipline still applies. He named specifically: =/code-review= before every commit and =/voice personal= on every commit message (he flagged this as by far the most common). The rest of CLAUDE.md / commits.md / testing.md / verification.md still binds. + +Action: review against rulesets' draft, merge the better framing of each section, decide where the canonical version lives (rulesets' workflow vs claude-rules vs both). + +* Overview + +A mode Craig switches on to drop the approval gates between work items, so a pre-agreed batch of tasks runs straight through without "OK to proceed?" interruptions. Stays on until Craig turns it off, until a genuine question arises, or until the queue runs out. + +The point is throughput on work where the approval has already been earned upfront — a queue of tagged tasks Craig has already triaged, a "do all the =:quick:solo:= ones" sweep, a multi-step refactor with no design calls left. Approval gates are valuable when judgment is uncertain. They are friction when the decision is already made. + +This is *not* a license to skip the engineering discipline that keeps work shippable. Code review, voice pass, testing, and verification all stay on. The gates this turns off are the *interaction* gates — "I drafted a commit message, approve?" / "Plan looks like X, OK to start?" / "Ready to push?" + +* When to Use This Workflow + +Craig activates it with any of: +- "no-approval" / "no approvals" +- "no need for approval gates" +- "do all <selector> with no-approval" (e.g. "do all =:quick:solo:= tasks with no-approval") +- Queuing several tasks in =todo.org= followed by any phrase above +- Any equivalent phrasing that signals he does not want to be re-asked between items + +Deactivates when: +- Craig says it is back on (any explicit "approvals back on" signal) +- A new top-level user message arrives that does not reaffirm no-approvals — assume the mode resets when Craig switches topics +- A genuine question or unknown next step is hit — return control to Craig and exit the batch + +* What's Suspended + +Approval gates that step the workflow back to Craig for an "OK to proceed?" check: + +- The commit-message gate in =commits.md= Step 2 (draft inline, get approval, commit). Print the final commit message inline, then commit immediately. No "approve / request changes / open in editor" prompt. +- The PR-description gate in the same flow. Print the final body, then create the PR. +- The PR-review-reply gate. Print the final reply, then post. +- "Ready to start?" / "Plan looks like X, proceed?" gates before implementation work begins. +- "Move on to the next task?" gates between items in a queued batch. +- Per-task summary prompts at the end of each item. Give one short result line and proceed to the next. + +* What Stays On + +Engineering discipline gates that protect quality, not Craig's interaction time: + +- =/code-review= against the staged diff before every commit. Critical and Important findings still block. Minor findings still surface. No "proceed anyway" override unless Craig has given it explicitly for this batch. +- =/voice personal= against every publish artifact (commit messages, PR titles + bodies, PR review comments). The 41-pattern walk happens. The printed result just does not wait for approval. +- The full test suite + lint + compile before commit (=verification.md=). +- Fetch-and-reconcile in =commits.md= Step 0. +- Any destructive or irreversible operation per =CLAUDE.md= "Executing actions with care". Those need explicit consent regardless of the mode — force push, =rm -rf=, dropping a column. No-approvals is for *interaction* gates, not destructive-action consent. +- Anything specifically requiring Craig's design call, preference, or sign-off. Stop and ask. The batch ends here. +- Subagent review-gate cadence (=subagents.md=). Review each subagent's output before the next dispatch. + +* When to Break Out of the Batch + +Even with no-approvals on, return control to Craig immediately if: + +- A genuine ambiguity surfaces (multiple ways to do the next step, no clear default). +- A finding suggests the user's stated goal is wrong (e.g. the "fix" reveals the bug is elsewhere). +- =/code-review= surfaces a Critical or Important finding the batch cannot resolve safely. +- Tests fail in a way that needs Craig's judgment. +- The queued work is done and no obvious next item exists. +- Any guideline above says "stop and ask" — that wins over no-approvals. + +When breaking out, say so explicitly: "Pausing no-approvals batch — <reason>. Decision needed: <question>." + +* Activation Pattern + +When Craig invokes no-approvals (with one of the phrases above): + +1. Acknowledge the mode is on and name the scope ("no-approvals for the =:quick:solo:= tasks; stays on until done or until I hit a question"). +2. Identify the queue — the tasks named explicitly, or the org-tag selector, or "the next N tasks in todo.org". +3. Walk them in order. For each: do the work, run =/code-review= + =/voice personal= + tests as required, commit, move to the next. +4. Brief one-line status between items ("Task X done, on to Y"). +5. At the end of the queue: summarize what shipped, confirm batch is complete, return control. + +* Common Mistakes + +1. *Bypassing =/code-review= or =/voice personal=* — these are not approval gates, they are quality gates. They stay on. +2. *Plowing through a Critical finding* — Critical and Important findings still block. The batch pauses, the issue gets fixed, the batch resumes. +3. *Skipping destructive-action consent* — force push, =rm -rf=, dropping production data still need explicit consent per =CLAUDE.md= "Executing actions with care". No-approvals does not cover these. +4. *Continuing past genuine ambiguity* — if there are two reasonable ways forward, stop and ask. The batch's purpose is to skip *redundant* approvals, not to invent decisions Craig did not pre-agree to. +5. *Forgetting to surface progress* — Craig still wants the one-line status between items so he knows what is happening. +6. *Carrying no-approvals across sessions or unrelated user messages* — assume it resets when the work it was scoped for finishes, or when Craig moves to a different topic. + +* Living Document + +If a recurring pattern emerges (e.g. Craig wants the one-line status to include the commit SHA, or wants per-task tests skipped because the suite runs once at the end), fold it in. The mode is shaped by use — refine as the dogfooding signal arrives. |
