| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
| |
Craig's verdict on the all-red page styling: it reads like the system is about to crash. page-me and the work-the-backlog end-of-set page now use notify info --persist, still persistent and audible, never crash-scary. status-check's success and fail notifications keep their types, since a job outcome isn't a page.
The commit also carries the two loop-filed task records and the archive sweep counterpart from earlier tonight.
|
| |
|
|
| |
Two sends in the same minute whose text starts with the same phrase derived identical filenames, and the second silently replaced the first. A message was lost this way in the wild. An existing target now gets a -2/-3 stem suffix, extension preserved, on both the text and file paths. Four red-first tests reproduce the loss with a fixed timestamp so the same-minute case is deterministic.
|
| |
|
|
|
|
| |
Projects were falling behind on templates because somebody sent them a task: an untracked inbox drop read as a dirty tree to the stricter gates. The policy is now stated where the gates live: dirty means tracked modifications only, and untracked or gitignored files never block a template pull, a fast-forward, or a monitoring gate.
The audit found one offender. The inbox monitor's precondition used bare porcelain, counting the very drops it exists to process. It now checks tracked changes only, which is safe because the per-item commit already stages explicitly. The rsync WIP-guard keeps counting untracked files inside the synced source paths on purpose, since a half-written template is exactly the WIP it holds back.
|
| |
|
|
|
|
| |
A tracked or synced doc asserting "this machine is X" is false on every machine but its origin, and an agent trusting it reasons backwards all session. It happened live: a stale "ratio" claim steered a session running on velox. The new rule bans fixed identity claims in tracked/synced docs and requires the runtime derivation instead (uname -n, since the hostname binary is often absent). Describing the fleet stays legal. Claiming the current member doesn't.
startup gained a read-only probe that greps CLAUDE.md and notes.org for the pattern and surfaces hits as a judgment flag, never a block. Fixture-verified under bash and zsh.
|
| |
|
|
|
|
| |
Long autonomous sessions bloat or hit auto-compaction because /clear is a prompt keystroke no tool call can execute. Auto mode closes that gap: after the write-verified checkpoint, the agent derives its own tmux pane, arms self-inject.sh through tmux run-shell -b, and ends the turn so /clear and a resume line land at an idle prompt. The server-owned arm is load-bearing: a detached child of a tool call dies at the turn boundary. The pane must be derived before arming because ancestry detection can't work under the tmux server.
self-inject.sh joins the synced scripts with a six-test bats suite, tmux stubbed at the boundary. work-the-backlog now auto-flushes between tasks when context grows heavy, and its speedrun preset gained the per-item disposition rule: feature-level work gets a spec, unguessable decisions get a VERIFY, well-defined tasks get implemented. The mechanism was proven live in another project's session and its design note is preserved under docs/design/.
|
| |
|
|
|
|
| |
"synthesize backlog metrics" reads the JSONL union across personal projects and computes the per-run rollups, the trends, and the corrections signal (a later revert or fix touching an autonomous commit's files within ~14 days, a flag for review rather than a conviction). It writes one :agent:metrics: KB node linking back to prior synthesis nodes. Work and unknown projects are excluded by the denylist classification and reported per the refusal contract.
The step is read-only over the logs plus the single KB write. It never mutates the JSONL, todo.org, or any project tree.
|
| |
|
|
|
|
| |
One record per task at outcome time, appended to the project's .ai/metrics/work-the-backlog.jsonl. The field table follows the spec, with commit_sha called out as the corrections-signal key and comma-separated when a task decomposes into several commits. A failed append warns in the run summary but never blocks or aborts the run.
I added the "failed" outcome the spec's error-handling section required but its enum missed: a mid-implementation failure leaves the tree working, gets surfaced, and the run continues.
|
| |
|
|
|
|
|
|
| |
The defer checklist gained its filing mechanics. A deferral VERIFY now dedups against an existing sibling before filing, since the deferred task stays TODO and every later run would otherwise re-file. Placement, heading, and body follow the todo conventions.
A quick-question gap routes to the pre-flight Q&A only under the speedrun preset, and only for one-line factual or preference picks. Three or more questions means the task is underspecified and files instead. The data-loss item never routes to the Q&A.
The batch-ask is one message with recommendation-first numbered options, and answers land as dated lines in the task bodies before the run starts. The page fires exactly once, on set-done or cap-hit, via notify --persist.
|
| |
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
| |
inbox.org's auto mode regains its "run this batch next?" ask, now chaining into work-the-backlog as an explicit second step after routing: the eligibility query over the queued batch, file-only, paging off, cap 1. Startup and wrap-up still never execute.
The no-approvals speedrun lands as the named preset: an explicit ordered list run under autonomous-commit + always-push + paging-on, every approval front-loaded into the seven-step pre-flight. Any phrase containing "speedrun" routes to the preset, with disambiguation notes in no-approvals.org and the index. The finer Q&A mechanics land with Phase 4.
I scoped the chain's task set to the queued batch rather than all of todo.org. The ask is "run this batch next?", and a batch-yes running an unrelated higher-priority task would be surprising.
|
| |
|
|
|
|
| |
work-the-backlog.org now owns the autonomous execution loop: the mechanical eligibility gate, the four-item defer checklist, the per-task quality bar, and the run-cap kill switch, fed a task set, session mode, and cap by its callers. I stubbed the pre-flight Q&A, waiver read, end-of-set page, and metrics record with pointers to their phases.
inbox.org's auto mode drops its execute step. Per-cycle item 3 routes and queues only, so the loop has one home. This is Phase 1 of the autonomous-batch execution spec.
|
| |
|
|
|
|
|
|
|
|
| |
This closes the build half of the wrap-up routing spec: Phases 2 and 4 here, with the engine and discovery already shipped.
inbox.org's "File as TODO" disposition now runs route_recommend on each keeper and stamps :ROUTE_CANDIDATE: <destination> on strong and weak matches, so the wrap-up router has a candidate set without ever scanning the standing backlog. wrap-it-up.org Step 3 gains the optional router after the inbox sanity check, with the gate-vs-optional split named in the prose: surface the batch with destinations and confidence labels, then go or skip. An empty set stays silent.
The go path is mechanical rather than prose-driven: the new route-batch helper lists candidates read-only, and on go extracts each subtree (children ride along, markers stripped, headings promoted), delivers it via inbox-send for provenance, and removes the local copy only after a successful send, rewriting todo.org per send so a crash never strands an already-sent task locally. Overlapping candidate spans (a tagged child inside a tagged parent) are a loud conflict, left in place with a non-zero exit, because routing either span would silently take the other along.
A 13-test bats suite covers list/backlog exclusion, empty-set silence, delivery with provenance and children, promotion, drawer pruning, the no-todo.org destination, failed-send recovery with the marker intact, the nested-candidate conflict, and duplicate-marker dedupe. cross-project.md notes the router as a sanctioned cross-project write path.
|
| |
|
|
|
|
|
|
| |
The Phase A batch gains a read-only probe that prints one line when a project has an unsorted docs pile (a docs/design/ or stray docs/*-spec.org files) and no :LAST_SPEC_SORT: marker. Phase C surfaces the "run spec-sort" offer when the probe fired and stays silent otherwise.
The stray-root check uses find instead of the spec's compgen sketch: compgen is bash-only and zsh aborts on an unmatched glob, so the original snippet false-negatived on stray root specs under zsh. The spec's snippet is updated with a note, and the probe is fixture-verified in both shells across the four project shapes.
I also fixed startup.org's reference to the encourage-kb-contribution spec's pre-pilot path and sent .emacs.d the convention-live note with the id-index ask.
|
| |
|
|
|
|
|
|
| |
spec-sort is Phase 2 of the docs-lifecycle build. It proposes the sort (spine-predicate classification, an evidence panel per candidate, a conservative keyword proposal) and a human confirms every move with --confirm/--skip. Terminal states need an explicit --reason, recorded in the status history.
--apply is fail-safe. It refuses a dirty worktree, validates then writes from a recorded plan file, names applied and not-applied work with a git restore recovery recipe on mid-apply failure, and exits non-zero on post-apply residue. Moves land in docs/specs/ with the -spec.org suffix, a status heading carrying :ID: and a dated history line, and the two-sequence keyword header. file: links across the project-owned roots are recomputed, including a moved doc's own outbound links. Session archives and synced template paths are reported, never rewritten, with the canonical claude-templates file named. A successful run stamps :LAST_SPEC_SORT: in .ai/notes.org.
The 33-test bats suite is glob-discovered by make test. A dry run against rulesets' own pile matches the expected five candidates.
|
| |
|
|
|
|
| |
Phase 1 of the docs-lifecycle build. claude-rules/docs-lifecycle.md captures the shape: formal-vs-notes location split (docs/specs/ vs docs/design/), an authoritative org-keyword status heading with dated history and an :ID: UUID, the two-sequence keyword header that keeps decision cookies computing, named owners for every transition, and the one-grep status board.
The four workflows each take their piece: spec-create emits into docs/specs/ and stamps DRAFT in the template; spec-review checks location (legacy spots stay reviewable until :LAST_SPEC_SORT: is stamped) and owns the DRAFT-to-READY flip plus the demote path; spec-response owns READY-to-DOING at decomposition, stamps :SPEC_ID: on the build parent, and always emits the flip-to-IMPLEMENTED task; task-audit reconciles DOING specs against their bound parent's keyword.
|
| |
|
|
|
|
| |
Phase 0 of the autonomous-batch (speedrun) build. todo-format.md now carries fixed cross-project definitions: :solo: is the autonomy/eligibility tag (buildable, agent-verifiable, no design deliberation — at most one or two quick upfront-answerable decisions, which the speedrun pre-flight Q&A batches), and :quick: is a ≤30-minute effort hint that never gates eligibility. task-review and task-audit now treat the tag assessment as mandatory — a pass that skips it is incomplete.
task-review's :solo: gate 3 also moves from "no upfront decision" to the no-deliberation form: the stricter wording predated the pre-flight Q&A decision and would have wrongly excluded tasks with a quick answerable question.
|
| |
|
|
|
|
| |
Six checks for specs covering a user-facing panel or control surface: name each list item's source, don't gate immediately-showable data behind a scan, don't ask users to retype discovered values, tense-correct destructive confirmations, review diagnostics/repair affordances as one flow, and make popups visually belong to their launcher. Conditional — non-UI specs skip it.
Promoted from archsetup's Waybar network-panel review (2026-06-30 handoff).
|
| |
|
|
|
|
|
|
| |
sweep-gitignore-tooling.sh decided gitignore-mode with an exact unanchored match on `.ai/`, so a project using the anchored `/.ai/` form was misclassified as track-mode and silently skipped — which left .emacs.d's tracked tooling on a public GitHub mirror until its 2026-06-30 scrub. Both forms now count for mode detection and per-pattern presence, and appended lines follow whichever style the file already uses.
Track-mode projects also get a new check: tracked tooling paths combined with a non-cjennings.net remote draw a loud WARN, since a track-mode repo on a public host is the exposure the convention exists to prevent. The convention itself is now written down in protocols.org: a non-cjennings.net remote means the tooling set is gitignored, a deliberate team-shared config being the only explicit exception, and a private remote is not proof of privacy because a server-side mirror hook republishes invisibly.
From the .emacs.d handoff (2026-06-30 tooling-exposure broadcast).
|
| |
|
|
|
|
| |
A parent whose child tasks are all resolved closes (DONE/CANCELLED + CLOSED) and archives on the next --archive-done; a parent with one or two open children gets those promoted to standalone level-2 tasks first. Carries the leaf-with-notes carve-out (a task whose only descendant is a dated design note is unstarted work, not a finished container — flag NEEDS-USER, never close) and a warning to verify open-child counts against a real subtree scan, not a fragile regex. Depends on --convert-subtasks running first so the counts are accurate.
From the .emacs.d handoff (2026-07-01 task-audit note).
|
| |
|
|
|
|
|
|
| |
Rewrites every level-3+ DONE/CANCELLED/FAILED heading into a dated event-log entry from its CLOSED cookie, enforcing the todo-format depth rule that interactive closes and --archive-done (level-2 only) leave unapplied. A new lint-org checker (subtask-done-not-dated) flags stragglers, and the clean-todo, wrap-up, open-tasks, and task-review workflows now run the converter before archiving.
Removing the CLOSED cookie keeps a DEADLINE or SCHEDULED cookie that shares its planning line, rather than dropping the whole line.
From the .emacs.d handoff (2026-07-01 convert-subtasks bundle).
|
| |
|
|
|
|
| |
org-lint validates links, drawers, blocks, and babel, but not heading well-formedness. These four catch hand-edit defects it stays silent on: an indented heading demoted to body text (the task vanishes from the agenda and never archives), bare stars with no title, a malformed priority cookie org rejected, and a level-2 DONE/CANCELLED with no CLOSED line. All judgment-only and regex-based, wired in after the existing dated-header check. The last one pairs with the new aging step, which archives an undated completed task immediately.
I tightened the indented-heading check to two-or-more stars. The proposed one-or-more-stars regex flagged indented single-star lines, but an indented single * is a valid plain-list bullet, not a lost heading, so it false-positived on legitimate lists (confirmed: three valid bullets flagged). A ** is never a bullet, so an indented one is unambiguously a demoted heading. Added a test that a single-star list stays silent.
|
| |
|
|
|
|
| |
A project's in-file Resolved section grew without bound: --archive-done only moved closures from Open Work into Resolved, same file. .emacs.d's todo.org reached 768KB that way. So --archive-done now has a second step: a Resolved subtree closed longer ago than tc-archive-retain-days (default 7), or with no parseable CLOSED date, moves out to archive/task-archive.org beside the todo file. Only the last week of closures stays in the file. The step honors --check, and tc-archive-retain-days nil disables it.
I added a guard the proposal lacked: the archive inherits the todo file's gitignore status. gitignore-mode projects gitignore todo.org, so without this the aging step would shed previously-private task history into a tracked archive, a leak on any public repo. When the todo file is gitignored and the archive isn't, the script adds the archive path to .gitignore before the first write. Track-mode projects leave both tracked. Covered by two tests in a temp git repo, one per branch.
|
| |
|
|
|
|
| |
The install bin loop linked every script under claude-templates/bin but never pruned orphans, so a deleted script left a dangling ~/.local/bin symlink. page-signal hit exactly this: the wrapper was removed 2026-06-12 but its symlink stayed, resolving to a dead target on the daily drivers. I added a prune step that drops symlinks pointing into claude-templates/bin whose target is gone, so any removed script self-cleans on the next install.
I also added a protocols section naming the two paging channels: notify --persist at the machine, and the signal-mcp send_message_to_user tool when away from it. The pager account was never deregistered (only the page-signal script went away), so the live path is the MCP tool, and the section retires the script for good.
|
| |
|
|
| |
I added route_recommend.py, a pure recommend(item, projects) → (destination, confidence). It has strong, weak, and none tiers, word-boundary literal matching that also handles dot-stripped name aliases, and a deterministic tie-break that downgrades an ambiguous top-tier tie to weak. An empty candidate list yields none. The CLI reuses inbox-send's discover_projects, so the candidate set is the same project universe inbox-send already knows. This covers Phases 1 and 3 of the wrap-up routing spec. The marker and router sub-tasks call it next.
|
| |
|
|
| |
A thin orchestrator that runs the behavior-preserving quality passes over a scope of existing code in order: /refactor, then readability-audit, then it surfaces the :refactor: tasks readability filed and any deferred /refactor findings. It leaves /simplify out, since that works the current diff rather than existing code.
|
| |
|
|
| |
.emacs.d resolves as emacsd and .dotfiles as dotfiles, in both inbox-send and the launch trigger. An exact basename match still wins, and --list shows the stripped name. triggers.md documents the same resolution so the spoken name is consistent across both.
|
| |
|
|
|
|
| |
suspend is a capture-only mid-session pause for an abrupt departure: it writes a resume-weighted entry and leaves the session anchor in place, so the next startup resumes from it. It's the capture half. Startup is the resume half. I registered it with its trigger phrases.
readability-audit is a language-agnostic pass over comments, file headers, names, and organization. The cheap comment and name fixes land inline. Structural findings get filed as :refactor: tasks. It feeds /refactor rather than duplicating it.
|
| |
|
|
| |
:BLOCKS: rulesets: was a malformed org tag, and the property form (:BLOCKED_BY: / :BLOCKS: carrying <project>: <what>) was more structure than the dependency needs. The blocking side now carries a plain :blocker: tag, mirroring :blocked: on the waiting side, with the which-project detail in the task body rather than a property. open-tasks.org reads the body for the blocking/requesting project; the scheme, the todo-format convention, and the inbox blocking-dependency handoff all move to the two-tag form. No property anywhere.
|
| |
|
|
|
|
|
|
| |
The :blocked: tag only marked the waiting side, so a blocker could stay unaware it was holding up another project: the dependency was visible to the one project that couldn't act on it and invisible to the one that could. This closes that gap. Setting :blocked: now requires a reciprocal inbox-send to the blocker, which files the work with a :BLOCKS: <project>: <what> property on its side. open-tasks.org surfaces :BLOCKS: tasks first, since clearing one unblocks another project (the highest-leverage pick), the mirror of pulling :blocked: tasks out of the cascade. Inbox process mode recognizes the blocking-dependency handoff shape, and the convention documents the resolution flow (drop :BLOCKS:, notify the waiter, who lifts :blocked:).
This works for any project pair, since the convention (todo-format.md) and the surfacing (open-tasks.org) live in the shared rule and workflow layer, not in one project.
Claude-Session: https://claude.ai/code/session_017PtX1nt1rtYVATuzmzBS4f
|
| |
|
|
|
|
|
|
|
|
| |
flashcard-to-anki.py's default_deck_name returned the input basename, so a deck built through flashcard-sync (which passes no --deck) was named after the file slug (refutation-drill) instead of the curated #+TITLE the phone deck should read (Refutations). flashcard-review.org already documented the #+TITLE behavior, and the script never matched it. default_deck_name now scans for a #+TITLE line (case-insensitive, trimmed) and falls back to the basename when there's none.
Five new tests cover title-drives-name, trimming, case-insensitivity, and the two basename fallbacks. The two old tests that asserted basename-always are replaced. The pre-staged script and test (validated 2026-06-21) applied cleanly red-to-green; their redundant copies are removed and the rationale doc kept.
Migration: deck IDs derive from the name, so decks previously built without --deck land as new decks on the next import. Old basename-named decks keep their history and can be deleted by hand.
Claude-Session: https://claude.ai/code/session_017PtX1nt1rtYVATuzmzBS4f
|
| |
|
|
|
|
| |
Reconciliation keeps each task honest on its own, but a single effort fragmented across several tasks (the agent-agnostic work, say) is hard to see and finish as a whole. Adds Phase C.5: read the open-task set, spot semantic clusters by judgment rather than a brittle keyword match, and propose per cluster either a merge (fold same-work members into one) or a parent-with-children grouping (related-but-distinct members). Proposes, never applies, until Craig picks; broader than Phase C's exact-duplicate fold.
Claude-Session: https://claude.ai/code/session_017PtX1nt1rtYVATuzmzBS4f
|
| |
|
|
|
|
| |
A task can be blocked by work owed by another project, and today it keeps getting recommended as "next" even though it can't move, while the blocker sits at low priority over there and the dependency stalls silently. Adds a :blocked: tag plus a :BLOCKED_BY: <project>: <what> property (todo-format.md) to mark the dependency, and teaches open-tasks.org Next Mode to pull :blocked: tasks out of the cascade pick and surface them in a dedicated "Blocked on other projects" section that names each blocker and offers an inbox-send nudge. Distinct from VERIFY, which waits on Craig rather than another project.
Claude-Session: https://claude.ai/code/session_017PtX1nt1rtYVATuzmzBS4f
|
| |
|
|
|
|
|
|
|
|
| |
When a roam edit hits a live org-capture, the guard used to bounce the caller right away (surface to the user, or skip the cycle) even though the capture is usually a few seconds of mid-finalize that clears on its own. capture-guard gets a --wait poll mode: it re-checks every ~10s up to a budget (default 30s, each sleep capped so a short --wait never overshoots), returns the instant the capture clears, and reports blocked only at the deadline. The no-capture common case still returns instantly without sleeping.
Roam mode now uses --wait on every write, and the per-caller fallback fires only after the wait: an interactive run surfaces, the auto /loop defers to the next cycle (the loop cadence is the retry), wrap-up skips and self-heals.
Surfaced live this session: a transient capture blocked a roam reconcile and had cleared a minute later. Covered by three new bats cases (instant-when-safe, timeout-when-blocked, target-after-flag).
Claude-Session: https://claude.ai/code/session_017PtX1nt1rtYVATuzmzBS4f
|
| |
|
|
|
|
| |
The wrap-up valediction now always ends with "session wrapped." on its own line — a consistent, unmistakable end-of-session marker, since it's the last user-facing output before Step 6's silent teardown. Craig's request via the roam inbox.
Claude-Session: https://claude.ai/code/session_017PtX1nt1rtYVATuzmzBS4f
|
| |
|
|
|
|
|
|
|
|
| |
The roam repo's working tree is dirty most of the time (Craig captures into it constantly, and roam-sync only commits every 15 minutes), so roam mode's pull --ff-only failed on nearly every run and blocked triage. The auto inbox zero loop hit it every cycle.
Roam mode now never pulls. The scan reads the working-tree file directly, since that's already the latest local state, and the rare write removes the claimed items in place and then triggers roam-sync to commit and push. roam-sync already commits-first-then-rebases, so it handles the dirty tree, and the ownership partition (only this project touches its own prefixed lines) means its rebase can't conflict on the edit.
Trade-off: the roam-repo commit carries roam-sync's generic auto-sync message instead of a descriptive one. The provenance for routed tasks lives in the project's todo.org and session log anyway.
Claude-Session: https://claude.ai/code/session_017PtX1nt1rtYVATuzmzBS4f
|
| |
|
|
|
|
|
|
|
|
|
|
| |
A bare "wrap it up" now tears the session down after the valediction: it kills the ai-term buffer and the aiv-<project> tmux session (which takes claude with it) and restores geometry. "wrap it up with summary" or "and summarize" keeps the buffer. "wrap it up and shutdown" gates on this being the only live ai-term session, then powers the machine off through an abort-able Emacs countdown.
Teardown can't run inline because it kills the session claude runs in, so the valediction would never flush. Step 6 instead drops a basename-keyed sentinel after commit+push is verified, and a new Stop hook (ai-wrap-teardown.sh) does the teardown when the response ends, by which point the valediction has rendered. The hook is a no-op on every normal stop because the sentinel only exists after a teardown wrap.
The runtime lives in .emacs.d/modules/ai-term.el (cj/ai-term-quit, cj/ai-term-live-count, cj/ai-term-shutdown-countdown), and the rulesets side calls it via emacsclient. I routed that companion to .emacs.d, so the feature is end-to-end once it lands. The hook has 8 bats tests. The live teardown and shutdown paths are a manual checklist in todo.org.
Built from the proposal. I went with both summary qualifiers, the Emacs-timer countdown, and the live-count gate.
Claude-Session: https://claude.ai/code/session_017PtX1nt1rtYVATuzmzBS4f
|
| |
|
|
|
|
|
|
|
|
|
|
| |
I merged process-inbox, monitor-inbox, and inbox-zero into one inbox.org engine. A shared core (value gate, skeptical review, disposition ladder, reply discipline, capture-guard, priority-scheme check) holds the logic that used to be duplicated and cross-referenced across the three files. Each mode (process, monitor, roam) references the core by name instead of restating it.
Every trigger phrase still works, now routing to a mode, so there's nothing to relearn. I added the interactive auto inbox zero mode: ask for an interval, run roam mode on /loop, acknowledge-only on an empty cycle, surface a find to a queue gated on a yes. The fully-unattended /schedule pass stays vNext, tracked separately.
I repointed every live caller (INDEX, protocols, startup Phase C, wrap-up Step 3, triage-intake, broadcast) at inbox.org and its modes, then deleted the three old files. triage-intake and no-approvals stay separate by design. The value gate, dispositions, capture-guard, and reply discipline all behave as before.
Built from the Ready spec. Workflow-integrity and sync-check pass on both the canonical and mirror trees, the stale-reference grep is clean, and the full suite is green.
Claude-Session: https://claude.ai/code/session_017PtX1nt1rtYVATuzmzBS4f
|
| |
|
|
|
|
| |
An aborted org-capture can leave a heading with no title and no body (just stars and maybe a TODO keyword). Those belong to nobody and were piling up in the shared roam inbox.
inbox-zero now buckets them as empty in Phase B and removes them in Phase D in the same edit as the claimed items. An empties-only run still enters Phase D and commits, so the sweep runs on every triage, not only when this project owns something. A heading with any title or body is never touched.
|
| |
|
|
|
|
|
|
|
|
| |
Editing the roam inbox on disk while Emacs has an indirect org-capture buffer cloned from it reverts the base buffer under the capture: the capture can't finalize with C-c C-c, and a freshly-typed item can be lost. inbox-zero Phase D edits that file, which Craig captures into constantly, so the collision recurs every session.
I added a capture-guard helper that asks the running daemon whether any CAPTURE buffer's base buffer visits a given file (file-equal-p, so symlinks and path spelling don't matter), exiting non-zero with the names when so. No reachable Emacs or no capture means exit 0, so it never blocks a write that was safe.
Phase D calls it before the pull, not only before the remove, because the ff-only pull also rewrites the file on disk and would wedge a capture the same way. On a collision an on-demand run stops and asks Craig to finalize or abort. The wrap-up sub-step skips the roam reconcile without blocking the wrap, since the items are already filed and the next run reclaims them.
emacs.md gains the inverse of the reload rule: don't yank a file out from under the daemon's live buffers.
|
| |
|
|
| |
The no-attribution rules covered AI credit but not incidental mentions of tooling filenames in commit prose. The case that bit: a .gitignore commit naming .claude, CLAUDE.md, and .ai in its message leaks the tooling layer into a public log. Adds a tooling-path-enumeration ban with that gitignore case named, extends the Before-Committing scan, and adds the missing paths to the protocols keep-out list. Both carry the file-is-the-change and private-single-user-repo exemptions, so a rule edit or a rulesets commit can still name what it touched.
|
| |
|
|
|
|
|
|
| |
The spec-review/spec-response pair wrote findings to a sibling <spec>-review.org file that spec-response deleted once processed. The deletion left the iteration-history Artifacts line dangling and dropped the verbatim review. Keeping the file instead collided with spec-response's file discovery and its "no review files remain" done-condition.
Findings now live in the spec under a * Review findings section as TODO tasks with a [/] cookie, the same shape * Decisions already uses. The reviewer records findings there. The responder completes each in place (accept and modify finish DONE, reject finishes CANCELLED with the reason), and the readiness rubric gates on the cookie. A scope-expanding response re-runs the rubric and files any new obligation as a finding or decision before claiming Ready, because resolving every finding can still introduce unreviewed assumptions.
Also folds in two reviewer-practice principles: keep review and response roles explicit, and cite the source for external-dependency facts in a finding. Updates spec-create.org and the workflow INDEX so the trio describes one convention.
|
| | |
|
| |
|
|
| |
A `** <YYYY-MM-DD> …` heading carries no keyword, so todo-cleanup's --archive-done can never archive it and task-review drops it from selection. The new level-2-dated-header check (custom, like org-table-standard) emits a judgment item per offending heading so the wrap-up sweep routes it to the next morning's review. Judgment-only, never auto-fixed: the repair needs a DONE-vs-CANCELLED call and the original heading text. Three ERT cases cover it (flagged at level 2, clean for DONE+CLOSED, clean for a level-3 dated entry).
|
| |
|
|
| |
Recent session receipts read "promoted 0 / consulted no" across the board: the wrap-up KB-promotion check existed but fired too late, and nothing surfaced existing lessons to read. This adds the spec's four light prompts plus the read-side step it was missing. Startup gets two Phase C nudges (gated on the roam clone): a consult line listing project-relevant node titles, and a contribute line pointing at the best-practices node. Triage-intake and inbox-zero get a conditional end-of-flow capture reminder that fires only on real signal. Wrap-up gets an early reflection prompt at the top of Step 1 that feeds the existing receipt, so learnings are captured while fresh instead of reconstructed after the Summary. Ratifies the spec's five decisions and adds D6 (the read-side surfacing).
|
| |
|
|
| |
The old rule dated a resolved VERIFY at every depth, including the top level. A level-2 dated header carries no keyword, so todo-cleanup's --archive-done can never archive it and task-review drops it from selection. Now a top-level VERIFY closes like any other top-level task (DONE/CANCELLED + CLOSED:), and dated rewrites are reserved for level 3 and deeper. Updated the rule and the three places that encoded the old behavior: todo-format.md, respond-to-cj-comments.md, and process-inbox.org. Also repaired two pre-existing level-2 dated headers.
|
| |
|
|
| |
build_candidates() only scanned ~/.emacs.d, ~/code/*, and ~/projects/*, so ~/.dotfiles (a bootstrapped AI project living directly in $HOME) never showed in the launcher picker. I added it as an explicit candidate next to ~/.emacs.d. The maybe_add_candidate guard keys off .ai/protocols.org, so the line stays inert where ~/.dotfiles isn't bootstrapped.
|
| |
|
|
| |
Nothing used the cross-agent message system (send/recv/watch/status/discover/halt/resume over the inbox/from-agents/ file-IPC protocol). Every cross-project handoff goes through inbox-send instead. I removed the scripts, READMEs, workflow, tests, INDEX entry, the three startup.org wirings, and the legacy bin symlinks, then repointed helper-mode's escalation to inbox-send and noted the removal in the generic-agent-runtime spec.
|
| |
|
|
|
|
| |
Auto-mode sweeps now end with the date, time, and timezone on their own final line, so an away reader gauges each summary's freshness at a glance without computing it. The stamp prints on every sweep, including a quiet "no changes" one — there the stamp is the proof the loop ran.
Same-day addendum to the work-project auto-mode proposal.
|
| |
|
|
|
|
|
|
|
|
| |
Add an auto mode to the triage-intake engine: a self-running variant for when Craig is away but wants tight awareness. It runs the standard sweep on a short interval (default 20 min) as an in-session loop, accumulates findings instead of mutating state, and gates the mutations behind "close the triage" (flush the batch, keep looping) and "stop the triage" (flush, then stop).
A sweep advances nothing — no sentinel write, no todos, no mail actions, no commit. The scan window grows from the last close to the next, so nothing between sweeps is dropped, and the sentinel still means "everything before this timestamp has been scanned" — it just advances once per close. Each sweep reports deltas plus a running "responses awaiting your acknowledgment" list, the primitive an away user needs that a delta-only sweep loses.
The unacked list is durable in .ai/triage-intake-unacked.org so it survives a crash, a clear, or a restart — the away-from-desk case the mode exists for. Delivery is an in-session loop so MCP auth is inherited; a detached cron schedule stays out of scope and belongs to the morning-ops orchestrator, which can reuse this accumulate behavior as its triage limb.
Source proposal from the work project, design decisions ratified 2026-06-15.
|
| |
|
|
|
|
|
|
|
|
| |
Redefine "monitor the inbox" as the explicit behavior Craig wants: run one process-inbox pass now, then loop process-inbox every 15 minutes. The 15-minute loop was previously an opt-in background recipe; it's now the defined meaning of the phrase.
Gate the workflow at both ends on a clean worktree and a green full-suite run. Starting on a dirty tree lets the per-item auto-commit sweep up unrelated changes; starting on a red suite hides whether the monitor broke anything. On a dirty tree, offer to commit in discrete batches; on a red suite, offer to investigate — never start until both are satisfied, and leave the tree clean and green when the loop stops.
Add the no-approvals execute criteria: an accepted item self-applies only when agreed (passed the value gate and Skeptical Review), quick (under ~15 min including verification), and solo (no decision needed from Craig). All three commit and push at the end of the item; miss any and it files or, for shared-asset and convention changes, parks.
Broaden the Skeptical Review to run on every arriving task and file, not only shared-asset proposals — a core right/complete/simpler pass on everything, with the cross-project battery added for changes that sync to consuming projects.
|