| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
| |
Scope the zero-id-links acceptance check to links the sort actually rewrote (prose mentions of the syntax already exist and would false-positive a naive grep), add untracked-copy cleanup to the mid-apply recovery recipe, and refresh two stale prose spots (nudge skip condition, bats case list).
|
| |
|
|
| |
Canonical placement contract for every synced artifact of the feature; a :SPEC_ID: property binds a spec to its build parent so task-audit can police DOING specs by the parent's keyword; spec-sort --apply gains a fail-safe contract (clean-tree preflight, validate-then-write from a recorded plan, named recovery); id-link conversion is staged behind the executable .emacs.d id-index mechanism so no unclickable-link window exists; status confirmation is evidence-based with terminal states requiring a stated reason. Status stays DRAFT pending reviewer sign-off.
|
| |
|
|
| |
The original reviewer re-checked all nine fixes against its findings: all held, verdict ready. Two minors folded in first — a refinement note under Decision 2 and a nudge probe that also fires on stray docs-root specs.
|
| |
|
|
| |
Two independent reviews converged on the same blocker: the lifecycle keyword line replaced TODO/DONE, silently breaking the decision-task cookies — the spec's own [5/5] was hand-faked. The header is now two collision-free sequences and org computes the cookies. Also fixed: every status flip has a named owner (spec-response emits a tracked flip-to-IMPLEMENTED task, task-audit reconciles as the safety net), one classification predicate, spec-sort renames to -spec.org, an explicit relink data-safety contract, the .ai/notes.org marker + startup probe contract, a legacy-location grace rule so no spec is unreviewable mid-transition, the org-id resolution prerequisite, and the three-line transition definition.
|
| |
|
|
| |
Location split (docs/specs/ vs docs/design/), org-keyword status on a prepended top-level status heading (DRAFT READY DOING | IMPLEMENTED SUPERSEDED CANCELLED), org-id cross-doc links, a general docs-lifecycle rule, and a confirmed spec-sort retrofit with a startup nudge. The spec is the first resident of docs/specs/ and carries its own status heading. Status DRAFT pending review.
|
| |
|
|
|
|
| |
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.
|
| |
|
|
| |
five tests
|
| | |
|
| | |
|
| |
|
|
|
|
| |
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).
|
| |
|
|
| |
The public-reachability check excluded only the literal cjennings.net host, so a remote addressed through the ~/.ssh/config alias (git@cjennings:repo.git) read as public and drew a false WARN on rulesets itself.
|
| |
|
|
|
|
|
|
| |
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).
|
| | |
|
| |
|
|
| |
The new --archive-done aging step's first run on this repo moved 58 closed subtrees older than seven days out of todo.org's Resolved section into archive/task-archive.org, leaving the last week in-file. Confirms the feature end to end: this repo tracks its todo file, so the archive is tracked and no gitignore entry was added.
|
| |
|
|
|
|
|
| |
Verified ratio over tailscale: the roam clone and roam-sync timer are live and
syncing, matching velox. That closes the one-time per-machine setup, so the
standing open-instance note is cleared. The memory-sync task's only remaining
item is its manual-validation child, which needs a live cross-project session.
|
| | |
|
| |
|
|
|
|
| |
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 rule claimed the agent can't reach the other daily driver, so the only move was to flag the drift. That's false: both machines are on the same tailnet, and this session repaired ratio's dotfiles over tailscale ssh. So the rule now says reach the other box directly to sync, verify, or repair, with flag-it kept as the fallback for when tailscale is down.
I added a section on the connection mechanics: tailscale status lists the nodes, the tailscale IP and MagicDNS name always resolve, a bare hostname only resolves when MagicDNS is configured locally, and the first connection needs StrictHostKeyChecking=accept-new.
|
| |
|
|
|
|
| |
A red test suite at the start of work poisons every later "did I break this?" check: you can't tell your own regressions from pre-existing noise, and the end-of-work green bar stops being readable. verification.md now asks for a clean suite run before work begins, not only before commit. start-work runs it as Pre-work step 0.3 against the reconciled base.
I added two carve-outs the original proposal lacked: a project with no suite has nothing to baseline, and a suite that can't run is the existing "When You Cannot Verify" case rather than a blocker. The step lands after the reconcile, so the baseline reflects the base the work is cut from. The Phase 4 TDD red is called out as expected, distinct from a baseline failure.
|
| |
|
|
|
|
| |
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.
|
| |
|
|
|
|
| |
Recast the speedrun eligibility criteria as checkable gates, not adjectives: dropped the task-size gate so large tasks decompose into per-commit chunks, replaced the act-vs-file rule with a four-item defer checklist keyed on whether the failing test is writable from the task text, and added a pre-flight step that front-loads a run's decisions so it proceeds unattended after. Define :solo: and :quick: precisely enough to enforce in task-review and task-audit.
Also record the spec storage and lifecycle-status decision (org-keyword authoritative, drop the filename suffix) and the requirement to retrofit existing docs across projects.
|
| | |
|
| |
|
|
| |
Task audit. I folded two of Craig's cj decisions: coverage-summary.el stays a local-only helper (reframed from bug to chore, docs work only), and the flashcard-stats refutation exemption goes generic, a header-declared check-exemption that supersedes the old two-option fix. I noted that the unattended-cron task's v1 precondition has landed, so it's buildable now rather than blocked. And I grouped the three flashcard tasks (apkg converter, refutation mode, multi-tag reconcile) under one parent, since they all edit the same two scripts and want building together.
|
| |
|
|
| |
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.
|
| | |
|
| |
|
|
| |
spec to [#D]
|
| |
|
|
| |
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.
|
| |
|
|
| |
Any project with a codebase (including home and work) derives its codebase bugs' priority from a severity-by-frequency matrix. The priority is dictated, not argued. The mapping is fixed: P1 to [#A], P2 to [#B], P3 to [#C], P4 to [#D], with the bands defined per codebase. Features keep their roadmap judgment. Privacy, security, and safety defects are graded on severity alone. I preserved the worked-example bundle under docs/design.
|
| |
|
|
| |
.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.
|
| |
|
|
| |
I tightened the before-committing rule in verification.md and commits.md from "run tests" to "run the full suite as its own step and commit only on zero failures." A PreToolUse hook now backs it: it denies a test runner chained into git commit through an ungated connector, and lets the gated && form pass. I added a respond_deny helper. Tests cover the connector cases.
|
| |
|
|
|
|
| |
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.
|
| |
|
|
| |
When a task needs Craig's location, run whereami on velox instead of asking. On any other host, fall back to asking. The rule covers the whereami-fails case (never fabricate a location) and keeps the geolocated address out of shared artifacts.
|
| |
|
|
| |
I added a simplification mode for behavior-preserving clarity and size reduction: over-defensive guards, needless indirection, convoluted logic, redundant state, and legibility rewrites. It runs in the default full scan and on its own. For the lenses dead-code and duplication already own (identical-twin branches, plain deletion, repeated literals) it cross-references those modes instead of specifying detection twice. It's distinct from /simplify, which works the current diff. This sweeps existing code.
|
| |
|
|
|
|
| |
Wrap of the task-audit / blocked-deps / Anki-fix / wrap-teardown-unblock session. Archives the record and applies todo hygiene (Anki and the cancelled Morning-ops subtree archived to Resolved, one table reflowed to 120 cols).
Claude-Session: https://claude.ai/code/session_017PtX1nt1rtYVATuzmzBS4f
|
| |
|
|
| |
: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
|
| |
|
|
|
|
| |
The three ai-term companion functions (cj/ai-term-quit, -live-count, -shutdown-countdown) are now in .emacs.d/modules/ai-term.el, double-checked against the contract. Dropped the :blocked: tag and :BLOCKED_BY: property — the build dependency is resolved, only the manual end-to-end validation remains. With the Stop hook wired and the companion present, the feature is live: the next bare "wrap it up" now tears the session down.
Claude-Session: https://claude.ai/code/session_017PtX1nt1rtYVATuzmzBS4f
|
| |
|
|
|
|
| |
Marks the #+TITLE deck-name fix DONE (060a938) and adds a note on the flashcard multi-tag task that its preserved 2026-06-17 to-anki.py now predates this fix, so it must be re-derived against the current canonical rather than copied wholesale.
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
|
| |
|
|
|
|
| |
Registers :blocked: in the rulesets priority scheme, tags wrap-teardown :blocked: with a :BLOCKED_BY: emacsd property as the live example (it's genuinely stalled on the .emacs.d companion), and closes the two now-implemented tasks: the cross-project dependency surfacing and the task-audit consolidation phase.
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
|
| |
|
|
|
|
| |
Inbox-zero claimed two rulesets-prefixed roam captures and filed them as [#C] tasks: surface cross-project dependencies first in the what's-next workflow (a blocked-by tag plus decision-tree binding, spec-shaped), and have the task-audit workflow consolidate adjacent or related tasks into a merge or a parent-with-children grouping.
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
|
| |
|
|
|
|
| |
Walked the 12 never-reviewed open tasks (the audit's Phase F). All kept as-is — every one is a recent, factually-current idea, no kills or re-grades. Stamped LAST_REVIEWED on all twelve, clearing the unreviewed backlog. Tagged the Anki deck-name bug and the flashcard multi-tag reconcile :quick: :solo: — both are scoped, Claude-verifiable, and decision-free (the Anki fix already has a validated script + test).
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
|
| |
|
|
|
|
| |
Craig runs two daily drivers, ratio and velox, that need to stay in sync. The rule prompts every project session to consider whether an important machine-level change (dotfiles, a synced repo's clone or timer, a global config, a one-time bootstrap) needs to reach the other box, and to name the manual step when nothing carries it automatically. It carries the current open instance: the roam.git KB clone plus its roam-sync timer is confirmed on velox and still needs verifying on ratio.
Claude-Session: https://claude.ai/code/session_017PtX1nt1rtYVATuzmzBS4f
|