| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
| |
Two additions from Craig, both landing on the throwaway branch that already makes a bad night a deleted branch.
Pass 11 now finds refactoring opportunities alongside bugs, filing each as a graded task. Still find-never-fix: a fresh finding files a task and stops, because a just-found bug can be a misread (one was filed and retracted two fires apart on 2026-07-23). The task is the checkpoint.
New pass 12 implements the backlog's solo, decision-free tasks on the branch, off by default behind :SENTRY_MAY_IMPLEMENT:. It reuses work-the-backlog's unattended-loop contract: only the ready bucket runs, anything needing a decision defers to a VERIFY, and nothing pushes. The morning review is the gate. Its /review-code runs the premise check first (reproduce the bug before judging the diff), because a filed claim never gets a review, and that skeptical review is what makes fixing on a branch safe. A finding that fails its premise check isn't implemented.
The marker is separate from :COMMIT_AUTONOMY: on purpose: hygiene is a two-minute merge, implemented code is a review session, so the owner opts in per project.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Four proposals from other projects, reviewed and applied together.
wrap-it-up gains a Clear temp/ step in Step 3. temp/ is gitignored everywhere, so nothing there survives deletion. The step confirms before removing anything that reads as in-progress rather than throwaway, and skips where temp/ isn't gitignored. This closes the last open clause of the working/temp work from 2026-07-20.
interaction.md drops the fenced-code-block carve-out. Chat output carries no markup at all now, fences included. Fences don't invert the way inline spans do, but the carve-out kept pulling them back in.
sentry.org folds in four notes from its first two live runs elsewhere. Two are traps for anyone reviewing a night by git log: archive-done touches .gitignore on its first run, and a mirror-only project's quiet fires leave no commits at all. The others make property sweeps sanctioned quiet-fire work and split the task audit into a mechanical hourly subset plus a nightly judgment half.
The notes.org template now lints clean, down from four flags in every project on every sweep. Two of those were mechanical, so lint-org --fix anywhere would have rewritten the template and drifted it from canonical.
|
| |
|
|
|
|
|
|
|
|
| |
Sentry no longer checks email or messengers. Pass 3 loads only the calendar and PR/ticketing triage plugins. The mail and messenger ones stay out: cmail, Gmail, Telegram, Signal, chat DMs. A manual triage intake still scans everything. The probe follows, so a project whose only declared sources are mail or messengers now skips the pass instead of running it empty.
New pass 11 hunts bugs. It runs linters and static analysis, checks config sanity, and reads one rotating code area per fire so coverage builds over a night. Verified findings get filed as graded bug tasks. It never fixes unattended.
I dropped the suite run the order called for. Running the suite every fire is the per-pass anti-pattern this same file forbids, and the entry baseline already has the result.
The KB personal-project roots now cover ~/.dotfiles, which was classifying Unknown and blocking writes from there.
|
| |
|
|
|
|
|
|
| |
Auto mode is the away-from-desk mode. A sweep worth seeing should reach Craig's phone, not just print into a session he isn't watching. I folded a Phone delivery subsection into canonical triage-intake.org: a full-three-section sweep now pushes to the phone over Signal via agent-text. A pointer from End-of-sweep output and a Living Document note tie it in.
Signal-only, by Craig's ruling: a quiet sweep's "nothing" heartbeat never reaches the phone. Silent-until-signal governs the phone channel too, so it only fires on real signal. The in-session heartbeat stays as proof the loop ran.
Only the send half ships. Reply polling (the retired ntfy design's phone-recv) waits on the reply-correlation follow-up: a Signal reply fans out to every linked device and neither knows which page it answers. That spec owns the recv wiring. I re-pointed the transport off dead ntfy onto agent-text (the renamed pager). The mirror is synced and the DONE task records the deferral.
|
| |
|
|
|
|
| |
"page me" and "text me" now name distinct channels: page is the desktop notification, text is the Signal phone push, and "text and page me" fires both. Before, "page me" defaulted to desktop and the phone was an unnamed "on my phone" variant, so you couldn't name the phone without naming the machine.
I renamed the Signal tool agent-page to agent-text to match, with a deprecated agent-page shim delegating to it so callers and other machines don't break before their next install. The dispatch and tests are otherwise unchanged. I rewrote protocols.org "Reaching Craig", page-me.org, and work-the-backlog's away-run logic around the three phrasings, and updated the runbook.
|
| |
|
|
|
|
| |
The general triage plugins (personal Gmail, cmail, calendar, Telegram, GitHub PRs) are template-synced into every project, so the old "plugins present" probe self-activated triage everywhere. The sentry live trial caught it reaching personal inboxes from a project that isn't a triage target. Now a general plugin activates only when the project names its basename in a :TRIAGE_SOURCES: line in notes.org Workflow State. A project-specific plugin stays active by presence. The gate lives in triage-intake Phase 0, so it fixes the interactive over-pull too, and sentry's pass-3 probe reads the same signal.
Presence is capability, the declaration is activation. A project that declares nothing and owns no project plugin pulls nothing. Migration handoffs went to home and work. rulesets correctly declares nothing.
|
| |
|
|
|
|
| |
Auto triage-intake and auto inbox-zero now collapse an empty check to a single "<workflow> at HH:MM: nothing" line, matching the sentry quiet-fire heartbeat from Phase 1. Detection stays in-session, so the MCP-auth sources are scanned in full and only the output collapses. Inbox already had an acknowledge-only-on-empty rule, now unified to the standard format; triage's three-section sweep output gains the empty-sweep collapse.
Completes the silent-until-signal spec (Phases 2-5): the spec is the shared-policy home the three workflows reference, and a manual-testing entry covers the live-loop verification. Spec flipped to IMPLEMENTED.
|
| |
|
|
|
|
| |
A suspend now ends by detaching the tmux client viewing the aiv-<project> session, so the parked session drops out of the alt-space rotation instead of cluttering it. Detach is not teardown: the session and agent process stay alive in the background and only the view disconnects, so it runs inline as the last action (the handoff text is preserved in the pane and shown on re-attach) rather than deferring to a Stop hook the way the session-killing teardown must. Degrades gracefully when not in tmux.
Originated in archsetup as a local stopgap and reconciled to canonical here.
|
| |
|
|
|
|
| |
A sentry fire whose passes all probe-skip or no-op now writes a single "sentry at HH:MM: nothing" line instead of a full per-pass digest block. A fire that runs or queues anything writes the full digest as before. This is Phase 1 of the silent-until-signal policy. The live trial's fires 3-8 were walls of no-op digests, the noise this removes.
The "no silent skip" discipline is reconciled, not broken: inside a working fire every pass still writes its ran/skipped line, and a quiet fire's heartbeat is the explicit "nothing to do" record rather than a hidden skip.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
convention
Home proposed two linked cross-project norms and Craig approved rolling them out. Both now ship in the template so every project inherits them.
A new "Colloquialisms and Expansions" section in protocols.org maps Craig's shorthand to a defined action the agent applies without asking. Two seed entries: "put X on the list" appends to a session-scoped Before-Close Queue, and "tell <project> <message>" drops the message in that project's inbox via inbox-send. The set is extensible.
The queue lives under a "* Before-Close Queue" heading in the session anchor, so it resets when the anchor is archived at wrap. Anything that must outlive the session stays a todo.org task. wrap-it-up Step 1 gets a sub-step that works the queue oldest-first before the Summary, so any resulting edits ride the wrap commit, with unfinished items surfaced in the valediction rather than dropped.
I settled three design calls. The reference lives in protocols.org rather than a per-project notes.org (home's local reference), since a synced section is what makes it a shared norm. The queue lives in the session anchor, as home did. The wrap step sits at the front of Step 1 rather than a new half-step, which keeps the "Steps 1 through 5" framing intact. A documentation-integrity bats guards the wiring and the before-the-Summary ordering against a future edit or sync dropping it.
|
| |
|
|
|
|
|
|
|
|
| |
A task phrased as an absence ("find bugs until none remain," "refactor until nothing worthwhile is left," "clean it up") can't be :solo:, because it fails the verifiable-by-the-agent gate. Absence isn't falsifiable, so "done" is a judgment call, which is what :solo: forbids. This kept surfacing (the ai-launcher-hardening task is the live case) with no written recipe for fixing it.
todo-format.md gains a subsection, right after the :solo:/:quick: definitions, on converting a fuzzy goal into a measurable one: bound the surface (enumerate the units, that's the done-set), net the behavior with characterization tests, disposition every finding (fixed / filed / declined-with-reason, never "looked and it's fine"), and gate on an objective floor (static-analysis clean, suite green, coverage of the enumerated surface). The qualifying answer becomes a dispositioned report, not a claim of perfection, and the honest limit stays honest: "no visible bugs" means "every enumerated path passes its characterization set and clears the audit." Once a task carries those criteria it can carry :solo:.
work-the-backlog's keystone defer item now names open-ended goals as a specific, recognizable failure of test-writability, so a mistagged :solo: task with no writable acceptance test is deferred and routed to get criteria rather than guessed at.
start-work has the same Justify/Approach gate and wants the same pointer, but its skill lives outside rulesets, so that edit is a follow-up in its home.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
quality sweep
The rule already said "write a characterization test before refactoring" but not what one is or how many to write per unit. Two additions close that.
testing.md's "Adding Tests to Existing Untested Code" now defines a characterization test as recording what the code actually does, not what it should (Feathers' assert-wrong-read-the-real-value recipe), and requires the same Normal/Boundary/Error set as any unit rather than one happy-path capture. The reason is the useful part: on a characterization test the negative and boundary cases are the bug-finders, because untested legacy code is weakest at the empty input and the missing upstream, and pinning what it currently does there writes the wrong behavior down where it becomes a visible bug. A pinned case that turns out to be a bug graduates from recording current behavior to asserting correct behavior. In-unit bugs fall to this set. Composition bugs need a functional test.
The refactor-for-testability section gains the framing that when the untestable code is legacy you're hardening, extracting the pure core is the hardening, not a detour around it. A function you can't characterize without mocking tmux or git can't be refactored safely, so "needs too much mocking" is the signal to reshape it, never a license to skip the boundary and error cases.
code-quality.org's passes claim to preserve behavior, so it now states the precondition that makes that true: on untested scope, a characterization net comes first, or "behavior-preserving" is an assertion the green suite can't actually verify.
|
| |
|
|
|
|
|
|
| |
The sentry live trial surfaced this. A sentry inbox-zero pass running from the work project parked the whole 19-item roam inbox as a cross-project boundary crossing and refused to tidy it unattended, reading knowledge-base.md's work-denylist as "don't touch roam from work."
That over-reads the rule. The denylist is a confidentiality guard on one thing: promoting a durable fact into a new agents/ node, so work-confidential material stays out of the personal cross-machine store. Roam is a shared resource, not another project's product scope. Reading it and tidying the shared roam inbox are housekeeping any project may do, work included.
knowledge-base.md gains a "Scope of the denylist" paragraph stating that and naming the mis-park as the error it closes. sentry.org's inbox-zero pass and inbox.org's roam mode each get a one-line note pointing at the rule, so a future agent doesn't re-derive the refusal. Only durable-node promotion stays work-denylisted.
|
| |
|
|
|
|
|
|
|
|
| |
Phase 3 of the sentry supervisor: reconcile the existing roam writers and wrap-up so sentry's locks actually guard something, and its shutdown has one enforced entry point.
The roam-write lock only helps if every roam writer takes it, so both writers now do. knowledge-base.md's write recipe and inbox.org core §5 acquire the roam-write lock around their edit and trigger roam-sync instead of committing themselves. That closes a gap the one-git-owner rule already implied but the KB recipe still violated: the recipe told agents to run git add -A && commit && push against a tree that's chronically dirty from live captures, which could sweep an in-flight capture into a stray commit. roam-sync stays the roam repo's only committer. Agents edit-plus-trigger under the lock, and roam-sync.sh's header now states that contract instead of the old "agents commit inline" note.
Both writers degrade as the spec settled: an absent agent-lock proceeds unlocked (today's behavior), and only a present helper reporting the lock busy after its bounded wait defers or surfaces.
wrap-it-up.org gains a Step 0 that refuses while sentry is live. It checks the single-runner lock and points at "stop sentry" rather than archiving the anchor and tearing down the buffer under a still-firing loop. Both files derive the lock name the same way (sentry-<repo-basename>), so the guard and the engine agree. triage-intake.org notes that it also runs as sentry's triage pass under the no-approvals contract, with its trigger phrases unchanged.
|
| |
|
|
|
|
|
|
|
|
| |
Phase 2 of the sentry supervisor. sentry.org is the engine: an interval loop (default hourly) that walks a fixed pass list (roam pull, inbox zero, triage, todo cleanup, task audit, working-files hygiene, spec board, link integrity, git health, prep freshness) and commits each writing pass to a throwaway sentry/<date>-<host> branch. Nothing pushes. The morning teardown (review, squash-merge, delete) stays Craig's.
The file owns the whole engine: the :COMMIT_AUTONOMY: entry ticket, the interactive entry gates (clean tree, green suite, prior-branch check, ff-only reconcile) that run with Craig present, the single-runner and roam-write locks via agent-lock, the probe-work-session-context-commit pass contract, the digest and morning-approval queue, the skip-not-degrade safety model, the conditional fire-end suite, the multi-day stall notification, and the stop-sentry shutdown.
Every one of the spec's ten decisions and twelve review findings is reflected: host-suffixed branch so the two daily drivers don't collide, tmpfs lock homes so a lock never rides roam-sync to the other machine, roam-sync kept as the roam repo's only committer, spine-excluded dirty checks so sentry's own bookkeeping can't trip its safety skip, and the queue-don't-execute rule for every judgment or destructive action.
Phase 3 wires the roam writers (inbox.org, knowledge-base.md) to acquire the roam-write lock and adds the wrap-it-up guard. Until then the engine is documented but the companions don't yet cooperate. INDEX.org lists it under Tasks and planning.
|
| |
|
|
|
|
|
|
| |
New stdlib-only upcoming_birthdays.py reads ~/sync/org/contacts.org for :BIRTHDAY: properties and prints a daily-prep block: name, date, days-away, and the age turned when the birth year is known (1900 is the org-contacts unknown-year placeholder, rendered date-only). Birthdays inside 7 days come back flagged so a gift or plan gets prompted. 19 pytest cases cover the window boundaries, leap-day fallback to Feb 28, the placeholder year, and the CLI.
daily-prep gains a Phase A source that runs the script and a Heads-Up line that folds in the block, so contact birthdays the calendar doesn't carry still surface.
Built and tested in the home project. Promoted here because the daily-prep hook lives in this synced workflow and the contacts file is present on every machine.
|
| |
|
|
|
|
| |
Phase C now renders a TASKS / FYI / MISC digest with a two-option close offer. The per-source breakdown and the itemized action menu move to on-request. Phase D becomes the close and runs by default after the digest: file the TASKS items, run mail hygiene on every scanned account without itemized confirmation, advance the sentinel, tear down anything the sweep started. Prose sends under my name and destructive non-mail actions stay gated. The reroute modifier delivers outside-project items to their owners via inbox-send. The stay-open-until-confirmed exit loop is retired. I updated daily-prep's Sub-step 3b to match.
I ratified this in the work project on 2026-07-18 and applied it here as sent from that handoff (inbox 2026-07-18-1730-from-work).
|
| |
|
|
|
|
|
|
| |
The residue probe cut off at before:<anchor-YYYY/MM/DD> while the scan started at after:<anchor-epoch>. Gmail's before:<date> excludes the named day, so the anchor day fell between the two queries. Each sweep then advanced the anchor past that window and never looked back, so an evening anchor hid most of a day for good. That's the exact failure the probe was added on 2026-07-08 to prevent.
The probe now cuts off at the epoch, matching the scan. I hoisted the epoch rule to cover both anchored queries once rather than twice. I scoped it to the anchor windows so the date-slice walk's deliberate day resolution doesn't read as a bug.
home caught it: after acting on 38 messages the probe reported zero while a plain is:unread in:inbox still returned two messages from the anchor day. personal-gmail is the only source pairing an anchored scan with a residue probe, so nothing else needed the fix.
|
| | |
|
| |
|
|
|
|
| |
The meeting recorder switched to lossless FLAC on 2026-07-01, and the transcript workflow's scan globbed only .mkv and .m4a, so a .flac recording was silently never found. FLAC now threads through the audio-only path: found by the scan, transcribed natively by AssemblyAI with no ffmpeg extraction, kept on cleanup, and archived with its own gitignore pattern.
Adopted verbatim from work's handoff (2026-07-14-0105), diff-verified against the canonical.
|
| |
|
|
|
|
| |
Both helpers treated any pipe-led line as a table row, so ASCII art in an example block got mangled into a bordered table (a work file took a 1949-line reformat on 2026-07-09). The scanners now track the open block's type and skip its content. Only the matching end marker closes a block, so a literal end_src quoted inside an example block can't re-expose it.
The deeper cause was wrap-org-table's load-time dispatch: it fired when lint-org merely required the library, running the reformatter over files lint-org was only asked to report on. It now dispatches only when named as the entry script. lint-org's CLI is also report-only by default now. Writes require --fix, and the wrap-up workflow and lint command pass it.
|
| |
|
|
| |
The Signal pager reconcile found one pager identity, registered in velox's signal-cli, reachable from other machines only by hand-rolled ssh. agent-page wraps that: direct signal-cli on velox, ssh relay over the tailnet from everywhere else, a desktop-fallback hint when the relay fails, and the UUID target baked in so nobody pages the unregistered phone number again. Four bats tests stub ssh/uname/signal-cli to verify command construction; the real path was verified with a live phone push today. protocols.org's Paging Craig section now teaches both channels (notify for the desk, agent-page for the phone) and demotes signal-mcp to a velox-local nicety; page-me.org, work-the-backlog, and the INDEX carry the same two-channel story. Every project inherits on its next startup sync and make install.
|
| |
|
|
|
|
| |
task-review-staleness.sh expected a bare 2026-07-09 and treated an org inactive timestamp ([2026-07-09 Thu], the form matching the CREATED:/CLOSED: cookies in the same drawer) as unparseable. The count branch folded that into the stale count, so a freshly-reviewed task reported as never-reviewed, and a full review pass never dropped the startup nudge. Both the bare and bracketed forms now normalize to the ISO date. A value that is neither warns loudly to stderr (file:line:value) and stays out of the count, since a data error shouldn't hide as "never reviewed." task-review.org documents the accepted format.
Tested red/green: 5 new bats cases (bracketed fresh and stale, list-mode sort by real date, malformed warns and is excluded). Full suite 273 ok.
|
| |
|
|
|
|
| |
For a spec whose deliverable is a real UI, a design argued on paper is a guess. New claude-rules/ui-prototyping.md: research the category first, brainstorm the UX in the spec, build ~5 distinct working prototypes over one engine, iterate one to a final, and record a UI decision only once it's been seen working in a prototype. spec-create gains the step for non-trivial-UI specs. spec-review gates on it: research cited, final prototype linked, iterations in history, decisions backed by a prototype. Prototypes live at docs/prototypes/<spec-name>-prototype-<N>.html.
Worked example: archsetup's timer-panel spec and its three prototypes.
|
| |
|
|
|
|
| |
The google-docs MCP listMessages tool caps at maxResults=100 and exposes no pageToken, so an unread pile over 100 truncates silently and every later anchored sweep skips the tail below the cap. That's how a 300+ backlog built up unseen by 2026-07-08. Two Scan-section rules close it: when a scan returns exactly 100, walk the tail in date slices and dedupe by id, and never report resultSizeEstimate as a count. A cheap backlog-residue probe each sweep (before:<anchor>, maxResults=5) surfaces pre-anchor unread loudly, so an anchored "no changes" can't mask a window the scan never saw.
personal-gmail is the only gmail-family plugin here, so it's the only file that changed.
|
| |
|
|
|
|
|
|
|
|
| |
Every org document an agent writes carried `#+AUTHOR: Craig Jennings & Claude`. No template stamps that line. Agents copy it from a neighboring file, so one stray header propagates through everything generated afterward.
My own repos tolerate the co-author line. Employers whose policy is that work product carries employee names alone do not. An `#+AUTHOR:` line survives conversion into docx, a wiki page, or a PDF that reaches a customer.
I rewrote the header to `Craig Jennings` across the workflows, templates, specs, and design docs. The rule now lives in commits.md, so the next generated document starts correct rather than inheriting the mistake.
Archived session logs keep their original headers as a record of what happened. The two Codex-authored design docs keep their byline, because Codex wrote them and relabeling would be a false attribution rather than the removal of one.
|
| |
|
|
|
|
|
|
|
|
| |
Phase A step 3 guarded its template rsync only on whether rulesets' own source was clean, never on whether the project branch was current. When a branch is diverged or behind-and-dirty, Phase A.0 correctly declines to fast-forward, but the rsync then landed templates on the stale committed .ai/ baseline. The diff came out huge (measured against old content) and conflicted once the branch reconciled to upstream's newer templates. home hit it today: a 3-ahead/46-behind divergence produced ~25 files of phantom drift nobody authored.
I added a second guard: after Phase A.0's reconcile, it re-checks git rev-list @{u}...HEAD and skips the rsync when behind>0. It composes with the rulesets-clean guard, so both a stable source and a current branch are required before the sync runs. No-upstream and ahead-only both fall through and sync, which is correct.
It's deliberately not an auto-discard: a legitimate local stopgap in a synced file can't be told from accidental drift by content alone, so prevention is safe where blind cleanup isn't. Phase C's churn safety net still surfaces pre-existing dirt.
home proposed this via inbox handoff.
|
| |
|
|
|
|
| |
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.
|
| |
|
|
|
|
| |
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.
|
| |
|
|
|
|
| |
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).
|
| |
|
|
|
|
| |
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).
|
| |
|
|
| |
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.
|
| |
|
|
|
|
| |
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
|
| |
|
|
|
|
| |
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
|