From 8d790c0f5fd8d7841c92b6a4a9b56b64d945a795 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Thu, 2 Jul 2026 01:20:17 -0400 Subject: feat(backlog): pin the commit-autonomy waiver and its degrade contract The waiver is now a machine-read marker: ":COMMIT_AUTONOMY: yes" in notes.org's Workflow State, with ":LOOP_MAY_COMMIT: yes" as the separate grant for the unattended loop. An absent or non-yes marker reads as no, and the read is a fresh grep each run, never memory. A caller requesting autonomous-commit without the marker degrades to file-only, surfaced in both the run intro and the summary. I stamped rulesets' own :COMMIT_AUTONOMY: and left :LOOP_MAY_COMMIT: ungranted. Letting the recurring loop commit unattended is a separate trust decision. --- .ai/notes.org | 1 + .ai/workflows/work-the-backlog.org | 21 ++++++++++++++++++--- claude-templates/.ai/workflows/work-the-backlog.org | 21 ++++++++++++++++++--- todo.org | 4 ++-- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/.ai/notes.org b/.ai/notes.org index 404dd48..698cd4b 100644 --- a/.ai/notes.org +++ b/.ai/notes.org @@ -76,6 +76,7 @@ Format: * Workflow State +:COMMIT_AUTONOMY: yes :LAST_SPEC_SORT: 2026-07-02 Markers maintained by workflows to record when they last ran. Read by other workflows that gate their behavior on freshness. diff --git a/.ai/workflows/work-the-backlog.org b/.ai/workflows/work-the-backlog.org index 787fd4e..2c5e1b9 100644 --- a/.ai/workflows/work-the-backlog.org +++ b/.ai/workflows/work-the-backlog.org @@ -101,7 +101,21 @@ Autonomy changes who approves, not what quality means. Per task, non-negotiable: * Commit autonomy -=file-only= is the default: surface the diff, never commit. =autonomous-commit= is honored only when the project carries the per-project commit-autonomy waiver; absent the waiver, the request degrades to =file-only= and says so. The waiver read (location, the "has waiver" vs "loop may commit" split) and the degrade contract land with the feature's Phase 3 — until then, treat every run as =file-only= unless Craig has put the session in no-approvals mode himself. +=file-only= is the default: surface the diff, never commit. =autonomous-commit= is honored only when the project carries the commit-autonomy waiver, read fresh each run — never from memory of past runs or "this project usually allows it." + +The waiver lives in the project's =.ai/notes.org= *Workflow State* section as marker lines, the same shape as the workflow markers already there: + +#+begin_example +:COMMIT_AUTONOMY: yes +:LOOP_MAY_COMMIT: yes +#+end_example + +- =:COMMIT_AUTONOMY: yes= — the project has the waiver. An =autonomous-commit= request (the speedrun preset, or a manual run asking for it) is honored. +- =:LOOP_MAY_COMMIT: yes= — the *unattended loop caller* may also commit. It requires =:COMMIT_AUTONOMY:= alongside it; the split exists because "Craig-initiated speedrun may commit" and "the recurring loop may commit unattended" are different levels of trust. Without this flag the loop stays =file-only= even when the project holds the waiver. + +An absent marker means no. Anything other than a plain =yes= value also means no. The read is one grep of the Workflow State section — a lookup, not a judgment. + +*The degrade contract.* When a caller requests =autonomous-commit= and the required marker is missing, degrade to =file-only= and surface it in both the run intro and the run summary: "autonomous-commit requested, no :COMMIT_AUTONOMY: waiver in notes.org — running file-only." Never honor the request without the marker, and never drop to file-only silently — the first commits into a project that didn't opt in, the second hides why nothing got committed. * Bounding the run @@ -131,14 +145,14 @@ Each task outcome appends one JSONL record to =.ai/metrics/work-the-backlog.json =inbox.org= auto mode chains here as an explicit second step *after* its routing completes — never as a phase inside inbox processing. When a cycle files new items and Craig answers "run this batch next?" with yes, auto mode invokes this workflow with: - *Task set:* the eligibility query over the queued/filed items — status =TODO= + =:solo:= per the scheme header, priority-ordered. -- *Session mode:* =file-only=, paging off. (A project whose waiver opts the loop into commits can override once the Phase 3 waiver read lands.) +- *Session mode:* =file-only=, paging off. (A project carrying both =:COMMIT_AUTONOMY:= and =:LOOP_MAY_COMMIT:= markers opts the loop into commits — see Commit autonomy above.) - *Cap: 1.* The highest-priority eligible candidate runs, gets recorded, and the loop's next tick (or the next yes) continues from there. The loop has no human at kickoff of each task, so a needs-quick-decisions task defers with a =VERIFY= — the pre-flight Q&A is a speedrun capability, not a loop one. Startup and wrap-up never invoke this workflow. * Preset: the no-approvals speedrun -The named preset is a label for one flag combination, not a second code path: *explicit ordered list + =autonomous-commit= + always-push + paging-on*, with every approval front-loaded into a single pre-flight step. "No approvals" means all input first, then hands-off — not no input ever. =autonomous-commit= still requires the project's commit waiver; without it the preset degrades to =file-only= and says so. +The named preset is a label for one flag combination, not a second code path: *explicit ordered list + =autonomous-commit= + always-push + paging-on*, with every approval front-loaded into a single pre-flight step. "No approvals" means all input first, then hands-off — not no input ever. =autonomous-commit= still requires the =:COMMIT_AUTONOMY:= waiver (Commit autonomy above); without it the preset degrades to =file-only= and says so in the pre-flight intro. When Craig names a task set and says "speedrun": @@ -164,6 +178,7 @@ The finer pre-flight mechanics (classification guidance, the answer-recording co 8. *Skipping =/review-code= or =/voice= because nobody's watching.* Autonomy removes interaction gates, never engineering-discipline gates (same contract as =no-approvals.org=). 9. *Running past the cap.* The cap is the kill switch; hitting it means stop and surface, even mid-set. 10. *Paging per-task.* One page, end of set. +11. *Honoring =autonomous-commit= from memory.* The waiver is the marker line in =notes.org=, read fresh each run. "This project usually allows it" isn't a read. * Living Document diff --git a/claude-templates/.ai/workflows/work-the-backlog.org b/claude-templates/.ai/workflows/work-the-backlog.org index 787fd4e..2c5e1b9 100644 --- a/claude-templates/.ai/workflows/work-the-backlog.org +++ b/claude-templates/.ai/workflows/work-the-backlog.org @@ -101,7 +101,21 @@ Autonomy changes who approves, not what quality means. Per task, non-negotiable: * Commit autonomy -=file-only= is the default: surface the diff, never commit. =autonomous-commit= is honored only when the project carries the per-project commit-autonomy waiver; absent the waiver, the request degrades to =file-only= and says so. The waiver read (location, the "has waiver" vs "loop may commit" split) and the degrade contract land with the feature's Phase 3 — until then, treat every run as =file-only= unless Craig has put the session in no-approvals mode himself. +=file-only= is the default: surface the diff, never commit. =autonomous-commit= is honored only when the project carries the commit-autonomy waiver, read fresh each run — never from memory of past runs or "this project usually allows it." + +The waiver lives in the project's =.ai/notes.org= *Workflow State* section as marker lines, the same shape as the workflow markers already there: + +#+begin_example +:COMMIT_AUTONOMY: yes +:LOOP_MAY_COMMIT: yes +#+end_example + +- =:COMMIT_AUTONOMY: yes= — the project has the waiver. An =autonomous-commit= request (the speedrun preset, or a manual run asking for it) is honored. +- =:LOOP_MAY_COMMIT: yes= — the *unattended loop caller* may also commit. It requires =:COMMIT_AUTONOMY:= alongside it; the split exists because "Craig-initiated speedrun may commit" and "the recurring loop may commit unattended" are different levels of trust. Without this flag the loop stays =file-only= even when the project holds the waiver. + +An absent marker means no. Anything other than a plain =yes= value also means no. The read is one grep of the Workflow State section — a lookup, not a judgment. + +*The degrade contract.* When a caller requests =autonomous-commit= and the required marker is missing, degrade to =file-only= and surface it in both the run intro and the run summary: "autonomous-commit requested, no :COMMIT_AUTONOMY: waiver in notes.org — running file-only." Never honor the request without the marker, and never drop to file-only silently — the first commits into a project that didn't opt in, the second hides why nothing got committed. * Bounding the run @@ -131,14 +145,14 @@ Each task outcome appends one JSONL record to =.ai/metrics/work-the-backlog.json =inbox.org= auto mode chains here as an explicit second step *after* its routing completes — never as a phase inside inbox processing. When a cycle files new items and Craig answers "run this batch next?" with yes, auto mode invokes this workflow with: - *Task set:* the eligibility query over the queued/filed items — status =TODO= + =:solo:= per the scheme header, priority-ordered. -- *Session mode:* =file-only=, paging off. (A project whose waiver opts the loop into commits can override once the Phase 3 waiver read lands.) +- *Session mode:* =file-only=, paging off. (A project carrying both =:COMMIT_AUTONOMY:= and =:LOOP_MAY_COMMIT:= markers opts the loop into commits — see Commit autonomy above.) - *Cap: 1.* The highest-priority eligible candidate runs, gets recorded, and the loop's next tick (or the next yes) continues from there. The loop has no human at kickoff of each task, so a needs-quick-decisions task defers with a =VERIFY= — the pre-flight Q&A is a speedrun capability, not a loop one. Startup and wrap-up never invoke this workflow. * Preset: the no-approvals speedrun -The named preset is a label for one flag combination, not a second code path: *explicit ordered list + =autonomous-commit= + always-push + paging-on*, with every approval front-loaded into a single pre-flight step. "No approvals" means all input first, then hands-off — not no input ever. =autonomous-commit= still requires the project's commit waiver; without it the preset degrades to =file-only= and says so. +The named preset is a label for one flag combination, not a second code path: *explicit ordered list + =autonomous-commit= + always-push + paging-on*, with every approval front-loaded into a single pre-flight step. "No approvals" means all input first, then hands-off — not no input ever. =autonomous-commit= still requires the =:COMMIT_AUTONOMY:= waiver (Commit autonomy above); without it the preset degrades to =file-only= and says so in the pre-flight intro. When Craig names a task set and says "speedrun": @@ -164,6 +178,7 @@ The finer pre-flight mechanics (classification guidance, the answer-recording co 8. *Skipping =/review-code= or =/voice= because nobody's watching.* Autonomy removes interaction gates, never engineering-discipline gates (same contract as =no-approvals.org=). 9. *Running past the cap.* The cap is the kill switch; hitting it means stop and surface, even mid-set. 10. *Paging per-task.* One page, end of set. +11. *Honoring =autonomous-commit= from memory.* The waiver is the marker line in =notes.org=, read fresh each run. "This project usually allows it" isn't a read. * Living Document diff --git a/todo.org b/todo.org index c8c9b94..0732319 100644 --- a/todo.org +++ b/todo.org @@ -465,8 +465,8 @@ work-the-backlog.org written (canonical + mirror): caller contract (task set + s *** 2026-07-02 Thu @ 01:13:33 -0400 Phase 2 landed — both callers wired inbox.org auto-mode item 3 regained its "run this batch next?" ask, now chaining into work-the-backlog as an explicit second step after routing (eligibility query + file-only + paging off + cap 1). work-the-backlog.org gained the two caller sections: the auto-loop contract and the no-approvals speedrun preset (seven-step pre-flight → autonomous-commit + always-push + paging-on over an explicit list; finer Q&A mechanics deferred to Phase 4). Speedrun trigger phrases live in the workflow + INDEX; "speedrun" always routes to the preset, with a disambiguation note in no-approvals.org and its INDEX entry. Each caller independently exercisable. -*** TODO [#C] Phase 3 — file-only vs autonomous-commit gate :feature:solo: -Read the per-project commit-autonomy waiver; degrade autonomous-commit to file-only when absent and surface the degrade. Spec Phase 3 / D5. Verify: default file-only is the path taken with no waiver present. +*** 2026-07-02 Thu @ 01:18:07 -0400 Phase 3 landed — waiver-gated commit autonomy +Pinned the waiver format per D5: two marker lines in .ai/notes.org Workflow State — :COMMIT_AUTONOMY: yes (has the waiver) and :LOOP_MAY_COMMIT: yes (the unattended loop may also commit; requires the first). Absent or non-yes reads as no; the read is a fresh grep each run, never memory. Degrade contract written into work-the-backlog.org (surface in run intro + summary, never honor without the marker, never degrade silently); caller sections + Common Mistakes updated. Stamped rulesets' own :COMMIT_AUTONOMY: yes; :LOOP_MAY_COMMIT: deliberately not granted — Craig's call. .emacs.d holds the waiver too but its notes.org is its own scope; told via inbox-send to stamp its marker. *** TODO [#C] Phase 4 — defer checklist, pre-flight Q&A, end-of-set page :feature:solo: Implement the act-vs-file defer checklist (test-writability keystone, enumerated data-loss list, already-satisfied, design-deliberation), the speedrun pre-flight decision-gathering (gather → classify → order → intro → batch-ask → skip/answer), VERIFY-on-ambiguity filing, and the end-of-set notify alarm --persist page. Spec Phase 4 / D3 / D6 / D8. Verify: checklist only reduces what runs; pre-flight fires only under the speedrun preset. -- cgit v1.2.3