aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-11 02:33:10 -0500
committerCraig Jennings <c@cjennings.net>2026-07-11 02:33:10 -0500
commit828f70a788279e0019548385ccbce389c0313f4b (patch)
tree5a605be866c802d3d2ed850c4631de9fea7b52b8
parent95dd661b181863e2c0bb5d3aad9230c80fc6be78 (diff)
downloadrulesets-828f70a788279e0019548385ccbce389c0313f4b.tar.gz
rulesets-828f70a788279e0019548385ccbce389c0313f4b.zip
chore(todo): archive completed tasks, file build-to-prototype follow-upHEADmain
-rw-r--r--.ai/sessions/2026-07-11-02-30-inbox-clearout-six-proposals-shipped.org74
-rw-r--r--archive/task-archive.org109
-rw-r--r--inbox/PROCESSED-2026-07-11-0222-from-.emacs.d-ui-prototype-rule-proposal.org55
-rw-r--r--inbox/lint-followups.org8
-rw-r--r--todo.org115
5 files changed, 249 insertions, 112 deletions
diff --git a/.ai/sessions/2026-07-11-02-30-inbox-clearout-six-proposals-shipped.org b/.ai/sessions/2026-07-11-02-30-inbox-clearout-six-proposals-shipped.org
new file mode 100644
index 0000000..3555f8f
--- /dev/null
+++ b/.ai/sessions/2026-07-11-02-30-inbox-clearout-six-proposals-shipped.org
@@ -0,0 +1,74 @@
+#+TITLE: Session Context
+#+AUTHOR: Craig Jennings
+#+DATE: 2026-07-11
+
+* Summary
+
+** Active Goal
+
+Process the full project inbox (11 handoffs) and then the roam inbox. Craig chose to work the shared-asset proposals in order rather than deferring them, so the session became a full inbox clear-out with six proposals shipped.
+
+** Decisions
+
+- Craig approved all six shared-asset proposals after skeptical review, one batch at a time: triage-intake gmail cap, PR-review drop-praise, ui-prototyping rule, desktop-capture rule, bug-matrix double-count, staleness org-date parsing.
+- Placement calls: ui-prototyping and desktop-capture each got a standalone claude-rules/ file (not folded into existing workflows), matching the docs-lifecycle.md pattern spec-create already points at.
+- chime's staleness fix used the "both" approach: accept the org-native bracketed stamp AND warn loudly on genuinely-unparseable values, rather than silently counting them stale.
+- settings.json model flip (opus→fable, harness-written at 02:12) reverted to opus per Craig — matches the deliberate 2026-07-04 switch (73835a2).
+- Bare "wrap it up" → teardown mode.
+
+** Data Collected / Findings
+
+- The AI-attribution handoff's work had already landed as commit 6def7c4 (tree was clean); the 15 remaining "& Claude" files are all in .ai/sessions/ (historical, correctly held back). Confirmed agreement with everything the work session held back.
+- personal-gmail is the only gmail-family plugin rulesets owns, so the 100-cap fix touched one plugin.
+- The sent triage-intake copy carried the old "& Claude" author line; applied only the two Scan blocks, did not reintroduce it.
+- ~/.claude/settings.json is a symlink to the repo file, so a git checkout reverts both at once (not a hardlink).
+- Roam inbox churns fast (12 items at 01:01 startup, 6 at 02:16 process). Git history confirmed exactly 3 rulesets-owned items ever passed through and all 3 were filed — no rulesets item was missed; the count drop was foreign-item/other-machine churn.
+
+** Files Modified
+
+- Six proposal commits (see Next Steps for shas). Rules/skills: review-code/SKILL.md, voice/SKILL.md, voice/references/voice-profile.org, claude-rules/{commits,todo-format,verification}.md; new claude-rules/{ui-prototyping,desktop-capture}.md. Workflows: triage-intake.personal-gmail.org, spec-create.org, spec-review.org, task-review.org (+ mirrors). Script: task-review-staleness.sh + its bats (+4 tests) + mirrors.
+- todo.org: 5 tasks filed (org-table bug [#B], Signal pager [#C], 3 roam ideas [#C]). notes.org: :LAST_INBOX_PROCESS: stamped 2026-07-11. 11 inbox handoffs renamed PROCESSED-*.
+
+** Next Steps
+
+- All inbox work done; nothing carried forward. Filed backlog tasks await future sessions: org-table helpers data-loss bug ([#B] :bug:solo:, has a repro test), Signal pager doc ([#C], reconcile signal-mcp vs signal-cli first), and the 3 roam ideas.
+- Shipped shas: 81ca16f, 99bd213, 53f6ce6, 8ddd3d3, 06ca6c7, cfbabf1 (+ housekeeping b2aeaf6, 95dd661).
+
+KB: promoted 0 / consulted no
+
+* Session Log
+
+** Startup (2026-07-11 01:01 CDT)
+
+Ran startup.org Phases A.0/A/B. rulesets pull clean, make install nothing new, project repo current. .ai/ synced from templates. No session-context anchor (prior session wrapped cleanly). Read the 5 most recent session summaries and all 11 inbox handoffs. Verified the AI-attribution handoff's work already landed as commit 6def7c4 (tree clean). Created this anchor.
+
+** Inbox processing (Craig chose: file the 2 tasks, work proposals in order)
+
+Filed two todo.org tasks: [#B] :bug:solo: org-table helpers corrupt example blocks (graded Critical×rare = P2 = [#B]); [#C] :feature:spec: document/own the Signal pager (flagged the signal-mcp vs signal-cli/account-404211 reconcile). Replied to work (bug + attribution) and home (signal), marked those 3 inbox files PROCESSED.
+
+Skeptical-reviewed the two work proposals:
+- triage-intake.personal-gmail.org: clean 2-block Scan addition (100-cap date-slice walk + mandatory backlog-residue probe). Only other diff is the "& Claude" author-line regression, which I will NOT reintroduce. Low-risk correctness fix. Verdict: approve. personal-gmail is the only gmail-family plugin in rulesets.
+- PR-review tightening: (1) no praise at all on approvals — drop the "bare positive" carve-out at review-code/SKILL.md:453, :278, examples :458-465, and /voice pattern #40; lead with substantive pointer then verdict. (2) always print full inline prose at the gate — tighten review-code Phase 5 (:276) + commits.md Shape 1. Craig's own ruling from a real session. Verdict: approve.
+
+Both awaiting Craig's approve/park.
+
+** Work proposals shipped (Craig approved both)
+
+- 81ca16f fix(triage-intake): personal-gmail 100-cap date-slice walk + backlog-residue probe (canonical + mirror). Did NOT reintroduce the "& Claude" author line from the sent copy.
+- 99bd213 docs(review): drop praise from approve summaries (removed bare-positive carve-out from review-code Posted Summary Voice + voice #40 + voice-profile §40 examples/history + quick-ref table), require full inline prose at the gate (review-code Phase 5 + commits.md Shape 1).
+- make test green (269 ok, pytest 12), both authored as Craig, not pushed yet.
+- Replied to work on both; marked the 3 work inbox files PROCESSED.
+
+Remaining inbox proposals to work (Craig's chosen order): archsetup ui-prototyping (2 files), archsetup off-workspace-captures rule, chime staleness-parse, chime bug-matrix double-count.
+
+** Full inbox cleared — 6 proposals shipped, all 11 handoffs processed
+
+Shipped commits: 81ca16f (triage 100-cap), 99bd213 (drop-praise), 53f6ce6 (ui-prototyping rule), 8ddd3d3 (desktop-capture rule), 06ca6c7 (bug-matrix), cfbabf1 (staleness org-date TDD, +4 tests, suite 273 ok), b2aeaf6 (housekeeping: 2 tasks filed + processed markers + inbox marker). Replied to every sender (work, home, archsetup, chime). notes.org :LAST_INBOX_PROCESS: stamped 2026-07-11. Nothing pushed yet.
+
+FLAG: .claude/settings.json model flipped opus→fable at 02:12 (hardlinked to ~/.claude/settings.json, harness-written, not my edit). Reverts the deliberate 2026-07-04 opus switch (73835a2). Left unstaged — needs Craig's call (revert to opus, or accept fable).
+
+** Roam inbox-zero (Craig: "then inbox-zero again")
+
+Roam inbox had 6 items at process time (roam-sync churns fast). Bucketed: 3 claimed (rulesets:), 3 foreign (emacs.d ×1, archsetup ×2), 0 unowned, 0 empty. Filed the 3 rulesets items into todo.org (all [#C]: roam-only-startup investigation :spec:, keep-WIP-from-blocking-sync-gate :feature:, install-ai-on-PATH :chore:) — committed 95dd661. Removed the 3 rulesets items from the roam inbox (foreign left untouched), handed git to roam-sync → adeb011, pushed clean. Phase E done.
+
+Session state: 8 rulesets commits this session (6 inbox proposals + 2 housekeeping), roam inbox reconciled. Nothing pushed to rulesets origin yet. settings.json model-flip still unstaged/unresolved.
diff --git a/archive/task-archive.org b/archive/task-archive.org
index e52563d..1bff51a 100644
--- a/archive/task-archive.org
+++ b/archive/task-archive.org
@@ -1718,3 +1718,112 @@ CLOSED: [2026-06-24 Wed 05:46]
A scheduled headless morning run chaining the existing pieces: startup checks, the triage-intake scan, a system health check — producing the prep doc plus a report and a notify ping, with all remediation propose-only. Staged adoption from the 2026-06-11 insights report's "Self-Healing Daily Ops Orchestrator": read-only first; promote individual routine remediations to auto only after each has a track record. Known blockers to design around: headless MCP auth (interactively-authenticated servers are absent in cron runs) and the consent boundary (triage Phase D, anything destructive).
The triage limb can reuse triage-intake's *auto mode* (added 2026-06-15, see [[file:.ai/workflows/triage-intake.org]]) — its accumulate-don't-mutate sweep is the propose-only behavior this orchestrator wants. Auto mode itself runs in-session (inherited MCP auth); the orchestrator is the durable headless schedule, so the headless-auth blocker above is the part still on this task to solve.
+** DONE [#B] wrap-it-up teardown + "wrap it up and shutdown" :feature:
+CLOSED: [2026-07-01 Wed]
+:PROPERTIES:
+:CREATED: [2026-06-23 Tue]
+:LAST_REVIEWED: 2026-06-24
+:END:
+Two additions to =wrap-it-up.org=, designed by Craig (home, 2026-06-23). Item 1: bare "wrap it up" also tears down the session — kill the =aiv-<proj>= tmux session (takes =claude= with it), kill the vterm buffer, restore geometry. Teardown is the default; "wrap it up with summary" wraps without teardown (keeps the buffer readable). Must fire from a Stop/SessionEnd hook via a sentinel file, decoupled and last, so the valediction flushes before the session dies, and strictly after commit+push is verified. Item 2: "wrap it up and shutdown" → wrap, then a hard blocking gate (abort unless this is the only live =aiv-*= session), then an abort-able 10→1 countdown, then =sudo shutdown now=. Countdown can't run through the Bash tool (stdout buffers — prints all ten at once); needs a detached tty writer or an Emacs =run-at-time= timer. Companion: =cj/ai-term-quit= (and optional =cj/ai-term-live-count=) must live in =.emacs.d/modules/ai-term.el= — route there via inbox-send when building so both sides land together. Open decisions for Craig first: qualifier wording ("with summary" vs "and summarize"), countdown home (tty script vs Emacs timer), session-count mechanism (=tmux ls= / =pgrep claude= / helper). Shared-asset, review-gated. Proposal: [[file:docs/design/2026-06-23-wrap-teardown-shutdown-proposal.org][proposal]]. From home 2026-06-23.
+
+*** 2026-06-23 Tue @ 23:31:59 -0400 Built the rulesets side; companion routed to .emacs.d
+Craig's three decisions (2026-06-23): non-destructive qualifier is *both* "with summary" and "and summarize"; countdown is an Emacs =run-at-time= timer; the gate uses =cj/ai-term-live-count=. Built and pushed: =hooks/ai-wrap-teardown.sh= (Stop hook, sentinel-gated, 8 bats tests green), =hooks/settings-snippet.json= Stop wiring, =wrap-it-up.org= Teardown-mode section + Step 6 + checklist, INDEX trigger update. Architecture: both teardown and shutdown fire from the Stop hook via a basename-keyed sentinel (=/tmp/ai-wrap-teardown-<proj>=, =/tmp/ai-wrap-shutdown-<proj>=) dropped only at the end of Step 6 after commit+push, so the valediction flushes first. No bin script — the gate/countdown/teardown are all =emacsclient= calls into the companion. Companion spec (=cj/ai-term-quit=, =cj/ai-term-live-count=, =cj/ai-term-shutdown-countdown=) routed to .emacs.d via inbox-send. Remaining: .emacs.d lands the three functions, then the manual end-to-end validation below. Task stays DOING until both sides verify.
+
+*** 2026-06-23 Tue @ 23:40 .emacs.d received + filed the companion spec
+Per a roam-inbox FYI from .emacs.d (2026-06-23 23:38): both ai-term handoffs (multi-LLM support + this wrap-teardown companion spec) landed and are filed as .emacs.d tasks. The teardown one is flagged for its own focused session to land alongside the rulesets half. Part (c) is now in progress on the .emacs.d side.
+
+*** 2026-06-24 Wed @ 06:51:13 -0400 Unblocked — .emacs.d companion landed; feature now live
+The three companion functions are in =.emacs.d/modules/ai-term.el= (=cj/ai-term-quit= 1068, =cj/ai-term-live-count= 1087, =cj/ai-term-shutdown-countdown= 1109), matching the contract — double-checked the bodies: quit kills session+buffer+restores layout idempotently, live-count returns the gate integer, shutdown-countdown re-checks the gate (TOCTOU guard), runs an abort-able =run-at-time= countdown (C-g cancels), then a configurable =cj/ai-term-shutdown-command=. 13 ERT tests, headless-verified live (.emacs.d FYI 2026-06-24 06:44). Dropped =:blocked:= / =:BLOCKED_BY:= — the build dependency is resolved; only the manual end-to-end validation below remains. NOTE: with the Stop hook wired and the companion present, the feature is now functional — the next bare "wrap it up" will actually tear the session down. Run the validation below before relying on it.
+
+*** 2026-07-01 Wed @ 21:52:15 -0400 Plumbing pre-flight re-verified; only the eyes-on tests remain
+Fresh pre-flight, all green: Stop hook block in =~/.claude/settings.json= points at =~/.claude/hooks/ai-wrap-teardown.sh=, the symlink resolves to the rulesets canonical, no stale =/tmp/ai-wrap-teardown-*= sentinel, and all three companion functions are live in the daemon (=(t t t)=). Three =aiv-*= sessions live right now (=_emacs_d=, =archsetup=, =rulesets=), so the shutdown-gate refusal test has its multi-session condition available. Everything left in the checklist below needs Craig's eyes on a scratch session: buffer teardown + geometry restore, the qualifier opt-outs, the countdown render + C-g, and the push-failure guard.
+
+*** 2026-07-01 Wed @ 21:59:43 -0400 Manual end-to-end validation passed — all five tests, Craig's live run
+Craig ran the full checklist in a live Emacs/tmux ai-term setup: (1) bare "wrap it up" tore down after the valediction rendered, geometry restored, no lingering sentinel; (2) "with summary" / "and summarize" both wrapped without teardown, buffer stayed readable; (3) "wrap it up and shutdown" with another aiv-* session live refused the shutdown, named the other session, fell back to a normal wrap; (4) as the sole session, the 10→1 echo-area countdown rendered one-per-second, C-g cancelled cleanly, and a full run fired the (stubbed) shutdown command; (5) with the push made to fail, the wrap stopped at the failure and no sentinel was dropped. Works great — feature validated and live. Both sides complete: rulesets Stop hook + wrap-it-up Teardown mode, .emacs.d companion functions.
+** DONE [#C] Guard against hardcoded host identity in synced files :feature:solo:
+CLOSED: [2026-07-02 Thu]
+:PROPERTIES:
+:CREATED: [2026-06-22 Mon]
+:LAST_REVIEWED: 2026-06-24
+:END:
+A =CLAUDE.md= / notes file that asserts mutable environment identity as a fixed fact ("This machine is ratio", a current OS, an IP, "the laptop") is false on every machine the synced/tracked file lands on but one. It bit a real archsetup session: a stale "this machine is ratio" line made the agent reason backwards all session while on velox. Proposal: a claude-rule — don't assert mutable host/env identity as a fixed fact in a tracked/synced project file; derive it at runtime and name the command (=uname -n= for host; the =hostname= binary is often absent). Optionally a codify- or startup-time lint flagging "this machine is <name>" / "the current host is" style claims. Proposal: [[file:docs/design/2026-06-21-host-identity-guard-proposal.org][proposal]]. From archsetup 2026-06-21.
+
+2026-07-02 Thu @ 05:09:58 -0400 — Craig (speedrun pre-flight): rule + startup lint. A new claude-rules file plus a cheap grep probe in startup flagging host-identity claims in CLAUDE.md / notes.org fleet-wide.
+
+Resolution 2026-07-02: claude-rules/host-identity.md written (fixed-identity claims banned in tracked/synced docs, runtime derivation via uname -n, fleet-description carve-out, the archsetup worked failure) and linked machine-wide by make install. startup.org gained Phase A probe 13 (grep for "this machine/host/box is" claims in CLAUDE.md + notes.org, fixture-verified bash+zsh) and the Phase C host-identity flag line. Flags for judgment, never blocks.
+** DONE [#C] No-approvals speedrun — cross-project autonomous-batch mode :feature:spec:
+CLOSED: [2026-07-02 Thu]
+:PROPERTIES:
+:CREATED: [2026-06-15 Mon]
+:LAST_REVIEWED: 2026-06-24
+:SPEC_ID: 90f623cd-fdbe-4f5c-b63d-b2f84d9151cf
+:END:
+A named mode for coding projects: Craig names an ordered task set and says "speedrun" / "no approvals speedrun"; the set is worked autonomously, each task held to the full quality bar (TDD red→green, =/review-code=, =/voice= on the commit) and committed + pushed as its own logical commit, with all needed quick decisions gathered in one pre-flight Q&A (answer or "skip this") and a VERIFY filed for anything underspecified or needing deliberation, plus an end-of-set page listing completed + remaining + skipped tasks. Task size is not a gate — large tasks decompose into per-commit chunks. Surfaced by .emacs.d from a 2026-06-15 theme-studio session where the shape worked. Source proposal: [[file:docs/design/2026-06-15-fix-speedrun-workflow-proposal.org]] (.emacs.d handoff 2026-06-15). Build via =spec-create= when worked; we handle the task in priority order.
+
+Skeptical-review read (open design questions to resolve in the spec, not settled here):
+- *Is it a new workflow or a documented preset?* The proposal frames it as no-approvals + always-push session modes plus an end page. Decide whether it needs its own workflow file or is mostly documentation of a preset over the two existing modes.
+- *Where/how the page fires* — every task vs end-of-set, and via what. The paging surface is in flux (=page-signal= removed 2026-06-12), so reconcile against =notify --persist= or whatever paging stands now.
+- *Auto-pull vs explicit list* — whether the set comes from an explicit ordered list or a tag/priority query.
+- *Guardrails* — must refuse to speedrun tasks needing design decisions or carrying data-loss risk without a checkpoint (the sender's biased-safe unused-tile flag is the worked example).
+
+*** 2026-07-01 Wed @ 22:10:35 -0400 Phase 0 landed — hard tag definitions + review/audit enforcement
+todo-format.md gained the "Hard definitions: :solo: and :quick:" subsection under the scheme header (fixed across projects: :solo: = buildable + agent-verifiable + no deliberation, with one-or-two upfront-answerable quick decisions allowed per the ratified spec; :quick: = ≤30-min effort hint, never a gate). task-review.org: the two tagging sections are now explicitly mandatory ("a review that skips them is incomplete") and gate 3 was realigned from "no upfront decision" to the spec's no-deliberation form — the stricter old wording predated the pre-flight-Q&A decision and would have wrongly excluded quick-question tasks. task-audit.org: the re-assess bullet is marked mandatory and points at the todo-format hard definitions as canonical. Phases 1-6 (work-the-backlog extraction, callers, commit gate, checklist/Q&A/page, metrics, synthesis) remain.
+
+*** 2026-06-16 Tue @ 00:53:36 -0500 Spec written; design questions answered
+Craig's "your call" (2026-06-16) answered in [[id:90f623cd-fdbe-4f5c-b63d-b2f84d9151cf][the autonomous-batch execution spec]], which reconciles this with Phase E into one feature:
+- *Most effective / workflow-vs-preset:* one dedicated =work-the-backlog.org= workflow holds the execution loop; "fix speedrun" is a thin named preset (no-approvals + always-push + end page) feeding it an explicit list, and the inbox-zero loop feeds it a tag query. Pros of the shared workflow: one execution loop to audit, inbox-zero's three callers stay clean, both input shapes reuse one guardrail set. Cons: one more workflow file and a caller-to-workflow indirection. The con list is shorter and lighter than the duplication cost of two separate features, which is why the shared workflow wins. The pros carry the more important entries (single audit surface, clean seam).
+- *Paging:* end-of-set only, via =notify ... --persist= (reconciled past the removed page-signal wrapper).
+- *Auto-pull vs explicit list:* both — explicit list for the preset, tag/priority query for the loop.
+- *Effectiveness measurement (the trial Craig asked for):* the spec designs a per-task JSONL metrics log (=.ai/metrics/work-the-backlog.jsonl=), a corrections-in-next-session signal, and a periodic synthesis step that writes =:agent:metrics:= org-roam articles for later review — the "gather data + create org-roam articles" loop.
+*** 2026-06-29 Mon @ 03:48:09 -0400 Ratified the autonomous-batch execution spec
+Craig ratified all eight decisions in [[id:90f623cd-fdbe-4f5c-b63d-b2f84d9151cf][2026-06-16-autonomous-batch-execution-spec.org]] (revised this session — size gate removed, crisp four-item defer checklist, =:solo:= / =:quick:= definitions + task-review/audit enforcement, speedrun pre-flight Q&A). Spec Status → ready; implementation-ready across Phase 0–6. Decisions grew from six to eight during the revision.
+
+*** 2026-07-02 Thu @ 00:44:59 -0400 spec-response decomposition — :SPEC_ID: bound, spec DOING
+Stamped the spec's UUID on this parent, broke Phases 1-6 into the build tasks below (plus the flip task and a live-trial validation child), and flipped the spec's status heading READY → DOING per the transition-ownership table.
+
+*** 2026-07-02 Thu @ 01:07:29 -0400 Phase 1 landed — execution loop extracted into work-the-backlog.org
+work-the-backlog.org written (canonical + mirror): caller contract (task set + session mode + cap), five-outcome vocabulary, the loop, mechanical eligibility gate (TODO + :solo: per scheme header, safe-by-omission, no-scheme-header → don't run), four-item defer checklist, per-task quality bar, cap/kill-switch semantics, page + metrics stubs pointing at Phases 4-5. inbox.org's auto-mode per-cycle item 3 reverted to routing-only (yes-path execution removed; mode intro + closing line updated to match). INDEX.org entry added. make test green, sync clean; nothing invokes the new workflow yet.
+
+*** 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.
+
+*** 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.
+
+*** 2026-07-02 Thu @ 01:21:47 -0400 Phase 4 landed — checklist mechanics, pre-flight Q&A contract, page
+The four-item checklist (in since Phase 1) gained its mechanics: a VERIFY-filing subsection (dedup against an existing sibling first — the deferred task stays TODO, so without the check every run re-files; placement/heading/body per todo-format.md) and a quick-question routing subsection (discriminator: one-line factual/preference pick vs tradeoff-weighing; three-plus questions = underspecified = file; item 2 data-loss never routes to Q&A). Preset section gained the batch-ask contract (one message, recommendation-first numbered options per interaction.md, answers recorded as dated lines in the task bodies before the run). Page section finalized (fires once on set-done or cap-hit; notify --persist is the paging surface). Common Mistakes 12-13 added. Checklist only ever reduces what runs; pre-flight fires only under the preset.
+
+*** 2026-07-02 Thu @ 01:24:50 -0400 Phase 5 landed — per-task JSONL metrics log
+Metrics section written into work-the-backlog.org: one record per task at outcome time, appended to the project's .ai/metrics/work-the-backlog.jsonl (git-tracked, append-only, dir+file created on first append). Full field table per the spec (ts, run_id, project, caller, task, outcome, defer_reason, upfront_decision, wall_clock_s, commit_sha, review_findings), outcome slugs mapped to the prose vocabulary, commit_sha flagged as the corrections-signal key (comma-separated when a task decomposed into several commits). Added the sixth outcome the spec's readiness section demanded but the enum missed: failed (tree left working, surfaced, run continues) — wired into the Outcomes vocabulary and loop step 4. A failed append warns in the run summary but never blocks, reorders, or aborts execution.
+
+*** 2026-07-02 Thu @ 01:27:43 -0400 Phase 6 landed — synthesis step to org-roam
+Synthesis section written into work-the-backlog.org (trigger "synthesize backlog metrics", INDEX row added): discover the JSONL union across project roots, classify each project per knowledge-base.md's denylist before reading, exclude work/unknown projects with the refusal contract, compute per-run rollups + trends, compute the corrections signal (later revert/fix commit touching the same files within ~14 days — a flag for human review, not a conviction), write one :agent:metrics: KB node under ~/org/roam/agents/ with [[id:...]] links to prior synthesis nodes, pull-before/commit-push-after. Read-only over the logs plus the single KB write; never mutates JSONL, todo.org, or any tree.
+
+*** 2026-07-02 Thu @ 05:26:07 -0400 Live trial passed — first speedrun ran 3/3, every loop part exercised
+Craig named the ordered set (id-link conversion, host-identity guard, template-sync policy) and said it was the validation run. Pre-flight Q&A fired once (two questions, both answered, answers stamped as dated lines before the run); each task landed as its own reviewed commit under the waiver (78bbaae, b6a977c, ed75d3c); metrics JSONL carries one record per task (run c726f526); the end-of-set page arrived via notify --persist. Nothing needed a VERIFY this run (all three cleared the checklist). Craig's read: granted :LOOP_MAY_COMMIT: on the strength of the run.
+
+*** 2026-07-02 Thu @ 05:26:07 -0400 Flipped the spec DOING → IMPLEMENTED
+All six phases built and the live trial validated. Keyword, dated history line, and Metadata mirror all flipped per the transition-ownership table.
+** DONE [#B] inbox-send filename collision silently overwrote a message :bug:solo:
+CLOSED: [2026-07-02 Thu]
+:PROPERTIES:
+:CREATED: [2026-07-02 Thu]
+:END:
+From archsetup (2026-07-02 0543, found in the wild): two --text sends in the same minute whose text starts with the same phrase derive identical filenames, and the second silently overwrites the first — archsetup lost a message at 05:42 and had to resend. Severity data-loss x rare-edge = P2 = [#B].
+
+Resolution 2026-07-02 (auto-inbox-zero loop, standing yes): uniquify() guard in inbox-send.py — an existing target gets a -2/-3/... stem suffix, both send_text and send_file paths, extension preserved. Four red-first tests reproduce the loss (module-level with a fixed timestamp so the same-minute collision is deterministic, plus a CLI loss-proof check); 30/30 green.
+** DONE [#C] page-me notify styling — all-red too alarming :bug:solo:
+CLOSED: [2026-07-02 Thu]
+:PROPERTIES:
+:CREATED: [2026-07-02 Thu]
+:END:
+From Craig via the roam inbox (2026-07-02, routed by archsetup): the page notify's all-red styling "makes me feel like somehow the system is about to crash" — should be a persistent info-level notification.
+
+Resolution 2026-07-02 (auto-inbox-zero loop, standing yes): pages now use notify info --persist instead of notify alarm — page-me.org (all examples + prose, with Craig's verdict recorded) and work-the-backlog.org's end-of-set page. status-check's success/fail types untouched (job outcomes, not pages).
+** DONE [#C] Template sync with gitignored-only local changes :feature:
+CLOSED: [2026-07-02 Thu]
+From Craig via the roam inbox (2026-07-02, routed by archsetup): downstream projects should still pull template updates when their local changes sit entirely in gitignored files or directories — an inbox drop or a file left to read doesn't affect the templates, yet it currently holds the sync back and projects fall behind. When worked: verify how the sync gate actually detects dirtiness today, then let gitignored-only changes pass it.
+
+2026-07-02 Thu @ 05:09:58 -0400 — Craig (speedrun pre-flight): policy + audit. Scope read found startup's git gates already ignore untracked/ignored files; state the policy in startup.org and audit every dirty-check in the synced workflows to match (monitor-inbox's bare porcelain check is the known offender; tracked-modification blocking stays).
+
+Resolution 2026-07-02: template-freshness policy stated in startup.org Phase A.0 (dirty = tracked modifications only; untracked/gitignored never block pulls, ffs, or monitoring gates; the rsync WIP-guard named as the one deliberate exception — it holds back rulesets' own outbound WIP). Full audit of dirty-checks across synced workflows: startup's two git gates already complied; inbox.org monitor mode was the one offender — its precondition now uses --untracked-files=no with the explicit-staging rationale, and its close-out sweeps tracked changes only. triage-intake auto mode borrows monitor's gates, so it inherits the fix by reference.
diff --git a/inbox/PROCESSED-2026-07-11-0222-from-.emacs.d-ui-prototype-rule-proposal.org b/inbox/PROCESSED-2026-07-11-0222-from-.emacs.d-ui-prototype-rule-proposal.org
new file mode 100644
index 0000000..eeb60e7
--- /dev/null
+++ b/inbox/PROCESSED-2026-07-11-0222-from-.emacs.d-ui-prototype-rule-proposal.org
@@ -0,0 +1,55 @@
+#+TITLE: Proposal: UI features require a prototype phase before build-to-spec
+#+AUTHOR: Craig Jennings
+#+DATE: 2026-07-11
+
+* The rule (Craig approved promotion 2026-07-11)
+
+When a spec'd feature has a UI, don't build straight from the spec. After the
+initial spec, run several UI/UX prototype feedback loops — iteratively driving
+the remaining functionality alongside the look and feel — then fold what settled
+back into the spec. Only then "build to the prototype": the built feature should
+look and behave as close to the prototype as possible, and any deviation is
+documented in an addendum section of the prototype/spec itself.
+
+* Where it should live (rulesets session decides exact home)
+
+Two natural homes; probably both:
+
+1. The =brainstorm= skill's Phase 3. Today Phase 3 presents the design in chunks
+ and stops. Add: if the feature has a UI, the design isn't "accepted" until it
+ has been through a prototype UI/UX phase (several feedback loops), and the
+ spec records what the prototype settled. The spec's Next Steps then say
+ "build to the prototype," not "build to the spec."
+
+2. A spec-lifecycle rule (=docs-lifecycle.md=, or a small new workflow rule).
+ The lifecycle for a UI feature gains a prototype stage between DRAFT/READY and
+ build, and the spec carries a "Prototype & deviations" addendum section that
+ the build keeps current.
+
+Companion touch points to reconcile: =spec-create= (emit the prototype stage +
+the deviations-addendum section for UI specs), =spec-response= (a UI spec
+decomposes into a prototype loop first, then build-to-prototype tasks),
+=start-work= (its verify phase already drives the UI end-to-end; here the bar is
+"matches the prototype," with deviations logged).
+
+* Why — worked example (takuzu, 2026-07-11)
+
+Building the takuzu (Binairo) Emacs game. The spec chose "colored tiles, glyph
+overlay optional." Built straight to that and the first launch in Craig's actual
+terminal frame was all black — the dark background-color faces read as black and
+the cursor was a GUI-only =:box=, so the whole grid was invisible. The
+colored-tiles-are-readable assumption was false in the real environment. A
+prototype loop caught it on the first screenshot; had we "built to spec" and
+called it done, we'd have shipped an unusable board. The fix (glyphs as the
+primary signal, inverse-video cursor) is exactly the kind of adjustment that only
+surfaces by looking at the running UI, and it now needs to flow back into the
+spec so the build target is the prototype, not the original spec text.
+
+Jotto (the other game spec'd the same day) also has a UI and will follow the same
+path.
+
+* Requested action
+
+Fold the rule into the brainstorm skill and the spec-lifecycle rules so it
+governs every project's UI features, then re-sync. This proposal is the durable
+channel; the two game projects apply it locally in the meantime.
diff --git a/inbox/lint-followups.org b/inbox/lint-followups.org
index 9390037..85580a0 100644
--- a/inbox/lint-followups.org
+++ b/inbox/lint-followups.org
@@ -1,6 +1,8 @@
* 2026-07-02 Thu — Task-review health: 2 top-level [#A]/[#B]/[#C] tasks unreviewed for >30 days (daily review may have slipped)
-* lint-org follow-ups — todo.org (2026-07-04)
-** TODO link-to-local-file — Link to non-existent local file "→id" (line 1387)
-
* 2026-07-04 Sat — Task-review health: 5 top-level [#A]/[#B]/[#C] tasks unreviewed for >30 days (daily review may have slipped)
+
+* lint-org follow-ups — todo.org (2026-07-11)
+** TODO link-to-local-file — Link to non-existent local file "→id" (line 1314)
+
+* 2026-07-11 Sat — Task-review health: 11 top-level [#A]/[#B]/[#C] tasks unreviewed for >30 days (daily review may have slipped)
diff --git a/todo.org b/todo.org
index f96bb5a..f14c906 100644
--- a/todo.org
+++ b/todo.org
@@ -39,6 +39,12 @@ Tags are assigned and refreshed by =task-audit=; =task-review= keeps them honest
* Rulesets Open Work
+** TODO [#B] Extend ui-prototyping rule with build-to-prototype :feature:
+:PROPERTIES:
+:CREATED: [2026-07-11 Sat]
+:END:
+.emacs.d proposal (2026-07-11, Craig-approved promotion), extending the ui-prototyping rule shipped tonight (=claude-rules/ui-prototyping.md=, 53f6ce6). The base rule covers research → prototypes → iterate → decisions-backed-by-a-prototype, but not the "build to the prototype" half. Add: after prototyping, fold what settled back into the spec and make the *build target* the prototype rather than the original spec text — the built feature should match the prototype, and any deviation is documented in a "Prototype & deviations" addendum section the build keeps current. Wire into four touch points: =brainstorm= Phase 3 (a UI design isn't "accepted" until it's been through the prototype loop; Next Steps say "build to the prototype"), =spec-create= (emit the deviations-addendum section for UI specs), =spec-response= (a UI spec decomposes into a prototype loop first, then build-to-prototype tasks), =start-work= (its verify phase drives the UI end-to-end; the bar becomes "matches the prototype," deviations logged). Worked example: the takuzu Emacs game — colored tiles read as all-black in the real terminal frame (dark faces + GUI-only box cursor), caught by a prototype loop on the first screenshot where build-to-spec would have shipped an unusable board. Multi-asset synced-rule change, so review-gated and needs a focused session; decide brainstorm-vs-lifecycle placement with Craig. Source: =inbox/PROCESSED-2026-07-11-0222-from-.emacs.d-ui-prototype-rule-proposal.org=.
+
** TODO [#C] Roam-only startup for .ai projects — investigate :spec:
:PROPERTIES:
:CREATED: [2026-07-11 Sat]
@@ -1132,115 +1138,6 @@ speculatively — defense-specific notations are narrow enough that each
skill should be driven by a concrete contract need, not aspiration.
* Rulesets Resolved
-** DONE [#B] wrap-it-up teardown + "wrap it up and shutdown" :feature:
-CLOSED: [2026-07-01 Wed]
-:PROPERTIES:
-:CREATED: [2026-06-23 Tue]
-:LAST_REVIEWED: 2026-06-24
-:END:
-Two additions to =wrap-it-up.org=, designed by Craig (home, 2026-06-23). Item 1: bare "wrap it up" also tears down the session — kill the =aiv-<proj>= tmux session (takes =claude= with it), kill the vterm buffer, restore geometry. Teardown is the default; "wrap it up with summary" wraps without teardown (keeps the buffer readable). Must fire from a Stop/SessionEnd hook via a sentinel file, decoupled and last, so the valediction flushes before the session dies, and strictly after commit+push is verified. Item 2: "wrap it up and shutdown" → wrap, then a hard blocking gate (abort unless this is the only live =aiv-*= session), then an abort-able 10→1 countdown, then =sudo shutdown now=. Countdown can't run through the Bash tool (stdout buffers — prints all ten at once); needs a detached tty writer or an Emacs =run-at-time= timer. Companion: =cj/ai-term-quit= (and optional =cj/ai-term-live-count=) must live in =.emacs.d/modules/ai-term.el= — route there via inbox-send when building so both sides land together. Open decisions for Craig first: qualifier wording ("with summary" vs "and summarize"), countdown home (tty script vs Emacs timer), session-count mechanism (=tmux ls= / =pgrep claude= / helper). Shared-asset, review-gated. Proposal: [[file:docs/design/2026-06-23-wrap-teardown-shutdown-proposal.org][proposal]]. From home 2026-06-23.
-
-*** 2026-06-23 Tue @ 23:31:59 -0400 Built the rulesets side; companion routed to .emacs.d
-Craig's three decisions (2026-06-23): non-destructive qualifier is *both* "with summary" and "and summarize"; countdown is an Emacs =run-at-time= timer; the gate uses =cj/ai-term-live-count=. Built and pushed: =hooks/ai-wrap-teardown.sh= (Stop hook, sentinel-gated, 8 bats tests green), =hooks/settings-snippet.json= Stop wiring, =wrap-it-up.org= Teardown-mode section + Step 6 + checklist, INDEX trigger update. Architecture: both teardown and shutdown fire from the Stop hook via a basename-keyed sentinel (=/tmp/ai-wrap-teardown-<proj>=, =/tmp/ai-wrap-shutdown-<proj>=) dropped only at the end of Step 6 after commit+push, so the valediction flushes first. No bin script — the gate/countdown/teardown are all =emacsclient= calls into the companion. Companion spec (=cj/ai-term-quit=, =cj/ai-term-live-count=, =cj/ai-term-shutdown-countdown=) routed to .emacs.d via inbox-send. Remaining: .emacs.d lands the three functions, then the manual end-to-end validation below. Task stays DOING until both sides verify.
-
-*** 2026-06-23 Tue @ 23:40 .emacs.d received + filed the companion spec
-Per a roam-inbox FYI from .emacs.d (2026-06-23 23:38): both ai-term handoffs (multi-LLM support + this wrap-teardown companion spec) landed and are filed as .emacs.d tasks. The teardown one is flagged for its own focused session to land alongside the rulesets half. Part (c) is now in progress on the .emacs.d side.
-
-*** 2026-06-24 Wed @ 06:51:13 -0400 Unblocked — .emacs.d companion landed; feature now live
-The three companion functions are in =.emacs.d/modules/ai-term.el= (=cj/ai-term-quit= 1068, =cj/ai-term-live-count= 1087, =cj/ai-term-shutdown-countdown= 1109), matching the contract — double-checked the bodies: quit kills session+buffer+restores layout idempotently, live-count returns the gate integer, shutdown-countdown re-checks the gate (TOCTOU guard), runs an abort-able =run-at-time= countdown (C-g cancels), then a configurable =cj/ai-term-shutdown-command=. 13 ERT tests, headless-verified live (.emacs.d FYI 2026-06-24 06:44). Dropped =:blocked:= / =:BLOCKED_BY:= — the build dependency is resolved; only the manual end-to-end validation below remains. NOTE: with the Stop hook wired and the companion present, the feature is now functional — the next bare "wrap it up" will actually tear the session down. Run the validation below before relying on it.
-
-*** 2026-07-01 Wed @ 21:52:15 -0400 Plumbing pre-flight re-verified; only the eyes-on tests remain
-Fresh pre-flight, all green: Stop hook block in =~/.claude/settings.json= points at =~/.claude/hooks/ai-wrap-teardown.sh=, the symlink resolves to the rulesets canonical, no stale =/tmp/ai-wrap-teardown-*= sentinel, and all three companion functions are live in the daemon (=(t t t)=). Three =aiv-*= sessions live right now (=_emacs_d=, =archsetup=, =rulesets=), so the shutdown-gate refusal test has its multi-session condition available. Everything left in the checklist below needs Craig's eyes on a scratch session: buffer teardown + geometry restore, the qualifier opt-outs, the countdown render + C-g, and the push-failure guard.
-
-*** 2026-07-01 Wed @ 21:59:43 -0400 Manual end-to-end validation passed — all five tests, Craig's live run
-Craig ran the full checklist in a live Emacs/tmux ai-term setup: (1) bare "wrap it up" tore down after the valediction rendered, geometry restored, no lingering sentinel; (2) "with summary" / "and summarize" both wrapped without teardown, buffer stayed readable; (3) "wrap it up and shutdown" with another aiv-* session live refused the shutdown, named the other session, fell back to a normal wrap; (4) as the sole session, the 10→1 echo-area countdown rendered one-per-second, C-g cancelled cleanly, and a full run fired the (stubbed) shutdown command; (5) with the push made to fail, the wrap stopped at the failure and no sentinel was dropped. Works great — feature validated and live. Both sides complete: rulesets Stop hook + wrap-it-up Teardown mode, .emacs.d companion functions.
-** DONE [#C] Guard against hardcoded host identity in synced files :feature:solo:
-CLOSED: [2026-07-02 Thu]
-:PROPERTIES:
-:CREATED: [2026-06-22 Mon]
-:LAST_REVIEWED: 2026-06-24
-:END:
-A =CLAUDE.md= / notes file that asserts mutable environment identity as a fixed fact ("This machine is ratio", a current OS, an IP, "the laptop") is false on every machine the synced/tracked file lands on but one. It bit a real archsetup session: a stale "this machine is ratio" line made the agent reason backwards all session while on velox. Proposal: a claude-rule — don't assert mutable host/env identity as a fixed fact in a tracked/synced project file; derive it at runtime and name the command (=uname -n= for host; the =hostname= binary is often absent). Optionally a codify- or startup-time lint flagging "this machine is <name>" / "the current host is" style claims. Proposal: [[file:docs/design/2026-06-21-host-identity-guard-proposal.org][proposal]]. From archsetup 2026-06-21.
-
-2026-07-02 Thu @ 05:09:58 -0400 — Craig (speedrun pre-flight): rule + startup lint. A new claude-rules file plus a cheap grep probe in startup flagging host-identity claims in CLAUDE.md / notes.org fleet-wide.
-
-Resolution 2026-07-02: claude-rules/host-identity.md written (fixed-identity claims banned in tracked/synced docs, runtime derivation via uname -n, fleet-description carve-out, the archsetup worked failure) and linked machine-wide by make install. startup.org gained Phase A probe 13 (grep for "this machine/host/box is" claims in CLAUDE.md + notes.org, fixture-verified bash+zsh) and the Phase C host-identity flag line. Flags for judgment, never blocks.
-** DONE [#C] No-approvals speedrun — cross-project autonomous-batch mode :feature:spec:
-CLOSED: [2026-07-02 Thu]
-:PROPERTIES:
-:CREATED: [2026-06-15 Mon]
-:LAST_REVIEWED: 2026-06-24
-:SPEC_ID: 90f623cd-fdbe-4f5c-b63d-b2f84d9151cf
-:END:
-A named mode for coding projects: Craig names an ordered task set and says "speedrun" / "no approvals speedrun"; the set is worked autonomously, each task held to the full quality bar (TDD red→green, =/review-code=, =/voice= on the commit) and committed + pushed as its own logical commit, with all needed quick decisions gathered in one pre-flight Q&A (answer or "skip this") and a VERIFY filed for anything underspecified or needing deliberation, plus an end-of-set page listing completed + remaining + skipped tasks. Task size is not a gate — large tasks decompose into per-commit chunks. Surfaced by .emacs.d from a 2026-06-15 theme-studio session where the shape worked. Source proposal: [[file:docs/design/2026-06-15-fix-speedrun-workflow-proposal.org]] (.emacs.d handoff 2026-06-15). Build via =spec-create= when worked; we handle the task in priority order.
-
-Skeptical-review read (open design questions to resolve in the spec, not settled here):
-- *Is it a new workflow or a documented preset?* The proposal frames it as no-approvals + always-push session modes plus an end page. Decide whether it needs its own workflow file or is mostly documentation of a preset over the two existing modes.
-- *Where/how the page fires* — every task vs end-of-set, and via what. The paging surface is in flux (=page-signal= removed 2026-06-12), so reconcile against =notify --persist= or whatever paging stands now.
-- *Auto-pull vs explicit list* — whether the set comes from an explicit ordered list or a tag/priority query.
-- *Guardrails* — must refuse to speedrun tasks needing design decisions or carrying data-loss risk without a checkpoint (the sender's biased-safe unused-tile flag is the worked example).
-
-*** 2026-07-01 Wed @ 22:10:35 -0400 Phase 0 landed — hard tag definitions + review/audit enforcement
-todo-format.md gained the "Hard definitions: :solo: and :quick:" subsection under the scheme header (fixed across projects: :solo: = buildable + agent-verifiable + no deliberation, with one-or-two upfront-answerable quick decisions allowed per the ratified spec; :quick: = ≤30-min effort hint, never a gate). task-review.org: the two tagging sections are now explicitly mandatory ("a review that skips them is incomplete") and gate 3 was realigned from "no upfront decision" to the spec's no-deliberation form — the stricter old wording predated the pre-flight-Q&A decision and would have wrongly excluded quick-question tasks. task-audit.org: the re-assess bullet is marked mandatory and points at the todo-format hard definitions as canonical. Phases 1-6 (work-the-backlog extraction, callers, commit gate, checklist/Q&A/page, metrics, synthesis) remain.
-
-*** 2026-06-16 Tue @ 00:53:36 -0500 Spec written; design questions answered
-Craig's "your call" (2026-06-16) answered in [[id:90f623cd-fdbe-4f5c-b63d-b2f84d9151cf][the autonomous-batch execution spec]], which reconciles this with Phase E into one feature:
-- *Most effective / workflow-vs-preset:* one dedicated =work-the-backlog.org= workflow holds the execution loop; "fix speedrun" is a thin named preset (no-approvals + always-push + end page) feeding it an explicit list, and the inbox-zero loop feeds it a tag query. Pros of the shared workflow: one execution loop to audit, inbox-zero's three callers stay clean, both input shapes reuse one guardrail set. Cons: one more workflow file and a caller-to-workflow indirection. The con list is shorter and lighter than the duplication cost of two separate features, which is why the shared workflow wins. The pros carry the more important entries (single audit surface, clean seam).
-- *Paging:* end-of-set only, via =notify ... --persist= (reconciled past the removed page-signal wrapper).
-- *Auto-pull vs explicit list:* both — explicit list for the preset, tag/priority query for the loop.
-- *Effectiveness measurement (the trial Craig asked for):* the spec designs a per-task JSONL metrics log (=.ai/metrics/work-the-backlog.jsonl=), a corrections-in-next-session signal, and a periodic synthesis step that writes =:agent:metrics:= org-roam articles for later review — the "gather data + create org-roam articles" loop.
-*** 2026-06-29 Mon @ 03:48:09 -0400 Ratified the autonomous-batch execution spec
-Craig ratified all eight decisions in [[id:90f623cd-fdbe-4f5c-b63d-b2f84d9151cf][2026-06-16-autonomous-batch-execution-spec.org]] (revised this session — size gate removed, crisp four-item defer checklist, =:solo:= / =:quick:= definitions + task-review/audit enforcement, speedrun pre-flight Q&A). Spec Status → ready; implementation-ready across Phase 0–6. Decisions grew from six to eight during the revision.
-
-*** 2026-07-02 Thu @ 00:44:59 -0400 spec-response decomposition — :SPEC_ID: bound, spec DOING
-Stamped the spec's UUID on this parent, broke Phases 1-6 into the build tasks below (plus the flip task and a live-trial validation child), and flipped the spec's status heading READY → DOING per the transition-ownership table.
-
-*** 2026-07-02 Thu @ 01:07:29 -0400 Phase 1 landed — execution loop extracted into work-the-backlog.org
-work-the-backlog.org written (canonical + mirror): caller contract (task set + session mode + cap), five-outcome vocabulary, the loop, mechanical eligibility gate (TODO + :solo: per scheme header, safe-by-omission, no-scheme-header → don't run), four-item defer checklist, per-task quality bar, cap/kill-switch semantics, page + metrics stubs pointing at Phases 4-5. inbox.org's auto-mode per-cycle item 3 reverted to routing-only (yes-path execution removed; mode intro + closing line updated to match). INDEX.org entry added. make test green, sync clean; nothing invokes the new workflow yet.
-
-*** 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.
-
-*** 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.
-
-*** 2026-07-02 Thu @ 01:21:47 -0400 Phase 4 landed — checklist mechanics, pre-flight Q&A contract, page
-The four-item checklist (in since Phase 1) gained its mechanics: a VERIFY-filing subsection (dedup against an existing sibling first — the deferred task stays TODO, so without the check every run re-files; placement/heading/body per todo-format.md) and a quick-question routing subsection (discriminator: one-line factual/preference pick vs tradeoff-weighing; three-plus questions = underspecified = file; item 2 data-loss never routes to Q&A). Preset section gained the batch-ask contract (one message, recommendation-first numbered options per interaction.md, answers recorded as dated lines in the task bodies before the run). Page section finalized (fires once on set-done or cap-hit; notify --persist is the paging surface). Common Mistakes 12-13 added. Checklist only ever reduces what runs; pre-flight fires only under the preset.
-
-*** 2026-07-02 Thu @ 01:24:50 -0400 Phase 5 landed — per-task JSONL metrics log
-Metrics section written into work-the-backlog.org: one record per task at outcome time, appended to the project's .ai/metrics/work-the-backlog.jsonl (git-tracked, append-only, dir+file created on first append). Full field table per the spec (ts, run_id, project, caller, task, outcome, defer_reason, upfront_decision, wall_clock_s, commit_sha, review_findings), outcome slugs mapped to the prose vocabulary, commit_sha flagged as the corrections-signal key (comma-separated when a task decomposed into several commits). Added the sixth outcome the spec's readiness section demanded but the enum missed: failed (tree left working, surfaced, run continues) — wired into the Outcomes vocabulary and loop step 4. A failed append warns in the run summary but never blocks, reorders, or aborts execution.
-
-*** 2026-07-02 Thu @ 01:27:43 -0400 Phase 6 landed — synthesis step to org-roam
-Synthesis section written into work-the-backlog.org (trigger "synthesize backlog metrics", INDEX row added): discover the JSONL union across project roots, classify each project per knowledge-base.md's denylist before reading, exclude work/unknown projects with the refusal contract, compute per-run rollups + trends, compute the corrections signal (later revert/fix commit touching the same files within ~14 days — a flag for human review, not a conviction), write one :agent:metrics: KB node under ~/org/roam/agents/ with [[id:...]] links to prior synthesis nodes, pull-before/commit-push-after. Read-only over the logs plus the single KB write; never mutates JSONL, todo.org, or any tree.
-
-*** 2026-07-02 Thu @ 05:26:07 -0400 Live trial passed — first speedrun ran 3/3, every loop part exercised
-Craig named the ordered set (id-link conversion, host-identity guard, template-sync policy) and said it was the validation run. Pre-flight Q&A fired once (two questions, both answered, answers stamped as dated lines before the run); each task landed as its own reviewed commit under the waiver (78bbaae, b6a977c, ed75d3c); metrics JSONL carries one record per task (run c726f526); the end-of-set page arrived via notify --persist. Nothing needed a VERIFY this run (all three cleared the checklist). Craig's read: granted :LOOP_MAY_COMMIT: on the strength of the run.
-
-*** 2026-07-02 Thu @ 05:26:07 -0400 Flipped the spec DOING → IMPLEMENTED
-All six phases built and the live trial validated. Keyword, dated history line, and Metadata mirror all flipped per the transition-ownership table.
-** DONE [#B] inbox-send filename collision silently overwrote a message :bug:solo:
-CLOSED: [2026-07-02 Thu]
-:PROPERTIES:
-:CREATED: [2026-07-02 Thu]
-:END:
-From archsetup (2026-07-02 0543, found in the wild): two --text sends in the same minute whose text starts with the same phrase derive identical filenames, and the second silently overwrites the first — archsetup lost a message at 05:42 and had to resend. Severity data-loss x rare-edge = P2 = [#B].
-
-Resolution 2026-07-02 (auto-inbox-zero loop, standing yes): uniquify() guard in inbox-send.py — an existing target gets a -2/-3/... stem suffix, both send_text and send_file paths, extension preserved. Four red-first tests reproduce the loss (module-level with a fixed timestamp so the same-minute collision is deterministic, plus a CLI loss-proof check); 30/30 green.
-** DONE [#C] page-me notify styling — all-red too alarming :bug:solo:
-CLOSED: [2026-07-02 Thu]
-:PROPERTIES:
-:CREATED: [2026-07-02 Thu]
-:END:
-From Craig via the roam inbox (2026-07-02, routed by archsetup): the page notify's all-red styling "makes me feel like somehow the system is about to crash" — should be a persistent info-level notification.
-
-Resolution 2026-07-02 (auto-inbox-zero loop, standing yes): pages now use notify info --persist instead of notify alarm — page-me.org (all examples + prose, with Craig's verdict recorded) and work-the-backlog.org's end-of-set page. status-check's success/fail types untouched (job outcomes, not pages).
-** DONE [#C] Template sync with gitignored-only local changes :feature:
-CLOSED: [2026-07-02 Thu]
-From Craig via the roam inbox (2026-07-02, routed by archsetup): downstream projects should still pull template updates when their local changes sit entirely in gitignored files or directories — an inbox drop or a file left to read doesn't affect the templates, yet it currently holds the sync back and projects fall behind. When worked: verify how the sync gate actually detects dirtiness today, then let gitignored-only changes pass it.
-
-2026-07-02 Thu @ 05:09:58 -0400 — Craig (speedrun pre-flight): policy + audit. Scope read found startup's git gates already ignore untracked/ignored files; state the policy in startup.org and audit every dirty-check in the synced workflows to match (monitor-inbox's bare porcelain check is the known offender; tracked-modification blocking stays).
-
-Resolution 2026-07-02: template-freshness policy stated in startup.org Phase A.0 (dirty = tracked modifications only; untracked/gitignored never block pulls, ffs, or monitoring gates; the rsync WIP-guard named as the one deliberate exception — it holds back rulesets' own outbound WIP). Full audit of dirty-checks across synced workflows: startup's two git gates already complied; inbox.org monitor mode was the one offender — its precondition now uses --untracked-files=no with the explicit-staging rationale, and its close-out sweeps tracked changes only. triage-intake auto mode borrows monitor's gates, so it inherits the fix by reference.
** DONE [#B] Wrap-up inbox/transcript routing to destination projects :feature:spec:
CLOSED: [2026-07-04 Sat]
:PROPERTIES: