| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| |
|
|
|
|
|
|
| |
A skill added to rulesets and pushed reached each machine's files on the next pull, but not its ~/.claude symlink. make install only links what isn't already linked, and a git pull doesn't run it. So a new skill stayed silently uninstalled until someone re-ran make install by hand. The flush skill sat in that gap from 2026-06-02 until a manual install today.
I added a make install step right after the Phase A.0 rulesets pull, the step that brings the skill's files in. It's idempotent: skips already-linked targets, links only what's new, and only writes symlinks under ~/.claude and ~/.local/bin. A grep keeps the all-skip case to one quiet line. Link, relink, and WARN lines get surfaced, and a new Phase C bullet handles them: a skill the harness already picked up mid-session is noted as available, one it didn't gets a restart prompt, a non-symlink collision goes to the user.
Now "add a skill, commit, push" is enough to reach every machine on the next session. The step also covers a newly-added rule or script, since make install links those too. The canonical template and the .ai/ mirror both carry the change.
|
| | |
|
| |
|
|
| |
Promoted the flush workflow into rulesets as a /flush skill plus a canonicalized SessionStart(clear) hook, then ran the four open :solo: tasks: start-work Justify and Approach gate additions, a task-review chain on task-audit, and lint-org follow-ups reconcile-on-write.
|
| |
|
|
|
|
|
|
|
|
| |
Every run appended a fresh dated "lint-org follow-ups" section with line-number-keyed entries, so the follow-ups file grew an unbounded pile of near-duplicate sections, kept entries whose finding had since resolved, and broke whenever the target file's line numbers shifted. Running an audit against a large todo.org surfaced exactly that drift: dead-link flags pointing at docs that now exist, and three stacked dated runs for one file.
Now lint-org rewrites the current file's section from the current run. Findings that no longer reproduce simply are not re-emitted, re-runs dedupe to one section, and entries key on checker plus message with the line as a trailing annotation, so a finding survives line shifts as the same entry. Other files' sections are left intact, and the strip step tolerates the old dated-header shape so existing follow-ups files migrate on first run. This changes the follow-ups file from an append-only log to the current outstanding findings per file.
task-audit's Phase C link-hygiene step now also reaps a matching dead-link entry when it fixes or verifies the link, scoped strictly to dead-link entries, so the audit and the follow-ups file stop drifting between lint runs.
Five follow-ups tests cover record-by-content, dedupe across runs, drop-on-resolve, and preserve-other-files. Mirrors synced.
|
| |
|
|
| |
A task audit verified the surviving tasks are factually honest but left their relevance and priority untouched, so keeping the list lean still needed a separate task-review run. Added Phase F: after the audit stamps :LAST_AUDIT:, run task-review on the oldest-unreviewed batch in the same pass. The two stay distinct (audit owns facts and :LAST_AUDIT:, review owns relevance and the per-task :LAST_REVIEWED:); chaining just refreshes both markers in one invocation. open-tasks does not invoke task-review, so nothing there needed to change. Mirror synced.
|
| | |
|
| | |
|
| |
|
|
|
|
| |
Paging never actually reached the phone before. signal-cli was registered as my primary number, so a page was that account messaging itself, and Signal mobile doesn't push-notify a self-message. I registered signal-cli with a separate Google Voice number (profile "Claude Pager") and pointed everything at it. page-signal now sends from that account to my Signal account by default, so a page lands as a normal third-party message and rings the phone.
The old --note-to-self default is gone, since note-to-self on the pager account wouldn't reach me. Sender and default recipient now come from PAGE_SIGNAL_ACCOUNT and PAGE_SIGNAL_TO with baked-in defaults. The send command pins the sender with -a, and --to also accepts a Signal account UUID, since my account hides its phone number. servers.json points signal-mcp at the new number. Verified end-to-end: live sends from the pager account notified the phone, and signal-mcp shows connected.
|
| | |
|
| |
|
|
|
|
| |
Prep docs are now born in daily-prep/YYYY-MM-DD-daily-prep.org and never move. A stable symlink at the project root, daily-prep.org, points at the current day's file and is the only thing that changes day to day. I replaced the old model where the doc was born in inbox/, yesterday's lingered there, and older docs were moved into a daily-prep/ archive.
Consumers resolve the root symlink instead of reconstructing a dated filename or scanning inbox/: the standup lookback, next-day Phase 2, and the Emacs opener. Phase 8 becomes a symlink repoint rather than an archive move, and triage-intake's prep-doc anchor fallback now points at daily-prep/ only.
|
| | |
|
| |
|
|
|
|
|
|
| |
Phase A's startup rsync copies template updates from rulesets into each project's .ai/, but nothing committed that churn, so it accumulated across sessions and eventually blocked Phase A.0's auto-fast-forward (git won't ff a dirty tree). Two projects hit it the same day.
I added a Step 4.0 to wrap-it-up.org that commits the churn as its own chore commit before the session-work commit, guarded so it only auto-commits synced .ai paths matching rulesets canonical byte-for-byte and surfaces anything that doesn't. startup.org Phase C now surfaces leftover churn at session start as the crashed-session safety net. Both skip the rulesets repo, where .ai/ is a committed mirror.
I also moved four misplaced PROPERTIES drawers in todo.org (DONE tasks) from after the resolution prose to immediately under the CLOSED line, so org parses them as real drawers.
|
| |
|
|
| |
Move the completed solo-batch, rename-tool, and coverage-fan-out tasks into Resolved, and file the lint-org judgment items for the next daily-prep.
|
| |
|
|
|
|
|
|
|
|
| |
Renaming an .ai artifact by hand is the kind of mechanical job that gets done incompletely: the canonical copy moves but the mirror doesn't, a reference in the INDEX is missed, a trigger phrase points at the old name. I'd also assumed a rename was costly because references scatter, when the index update is trivial and the drift check already guards it. So I built the discipline into a script instead of re-deriving it each time.
scripts/rename-ai-artifact.sh takes old and new basenames, moves the file in both the canonical and mirror trees, and rewrites every reference repo-wide on a token boundary so renaming "foo" can't corrupt "foobar" or "foo-bar". It rewrites the underscore module-name variant too (a hyphenated script imported as foo_bar via importlib), leaves the archived session records under sessions/ alone because they're history, and runs workflow-integrity + sync-check at the end to prove no drift. rename-artifact.org documents it and indexes the triggers.
Then I used the tool to do the rename that prompted it: the org-drill deck workflow and its helpers are now flashcard-named, since "flashcard" is the word you'd actually search for. The renamed set is flashcard-review.org plus flashcard-stats.py, flashcard-sync, flashcard-to-anki.py, and flashcard-diff-ids.py, with their tests, every reference, and the INDEX entry updated. The deck is still an org-drill deck under the hood, so the ":drill:" tag handling and the "drill deck" trigger phrases stay. I added "review/update the flashcards" alongside them.
Tests: 9 bats for the rename tool (including the prefix-collision and history-preservation edges), and the renamed script suites all pass under make test.
|
| |
|
|
|
|
|
|
|
|
| |
I split each into lanes so a reader can stop at the level that answers the question: Summary for "what does this do and what does it produce", Execution for the steps to follow, Reference for examples and edge cases, History for old decisions. Both files are large enough that an agent loading them at routing time pays for context it doesn't need yet.
startup.org keeps Summary, Execution, and Reference (workflow discovery and common mistakes moved under Reference). triage-intake.org gets all four, including a History lane for its design notes. Every instruction is preserved. The triage reorder ran through a content-preservation check that compared the multiset of content lines before and after, so only heading depth and lane grouping moved. Nothing was dropped or reworded.
workflow-integrity.py now counts "Summary" as a valid orientation heading, since that's the new top section both files lead with.
This is the pilot from the codex backlog, scoped to the two largest workflows. Whether the lanes actually cut session token use gets evaluated before any wider rollout.
|
| |
|
|
|
|
| |
daily-prep's Phase 3 re-implemented email/Slack/Linear/PR scanning inline (sub-steps 3b-3g, ~280 lines): the same fan-out, classify, and reactive-task work the triage-intake engine has owned since its 2026-05-26 plugin refactor. I collapsed those to four steps: 3b runs the engine, 3c surfaces today's reactive items as Day's Priorities thin links, 3d re-sorts by urgency, 3e writes the audit footer from the engine's per-source coverage.
Source coverage carries because the engine's Phase 0 globs both .ai/workflows/ and .ai/project-workflows/ plugins, so the work account's Gmail/Slack/Linear/GHE plugins are still scanned, and a source change now lives in one plugin instead of being duplicated here. I adapted the downstream references (the Prep-Doc-Structure rule, the Heads-up FYI source, the Recommended Approach Pattern reframed as engine-applied), dropped the orphaned Linear-digest note, and added a Living Document entry. The file goes 825 to 576 lines, and the prep-doc contract (Day's Priorities, Heads-up, Sources-checked footer) is unchanged.
|
| |
|
|
|
|
| |
Agents (and any future inventory tool) doing a naive recursive read of a project pick up node_modules, __pycache__, build output, and token artifacts even when those are gitignored, because a recursive read sees the disk, not git. I added a gitignore-syntax .aiignore at the repo root with the default skip list, and a protocols.org "Recursive Reads" subsection documenting the convention, the defaults to assume absent a file, and the lockfile policy (skip on agent reads, independent of git-tracking).
I did not wire the walking scripts (audit.sh, diff-lang.sh, sync-language-bundle.sh): they do targeted finds over .ai/.claude/bundle dirs, never whole-tree walks, so honoring .aiignore there would be dead code. That belongs in a future catalog tool.
|
| |
|
|
| |
From a pearl handoff: Phase 6 logged deferred and v1 work only in passing, so the implementer handoff was a re-read of the spec rather than a paste. I added a step that lifts the spec's Implementation phases section into a drop-in todo.org block: one [#B] TODO per phase plus a test-surface entry mirroring the Acceptance criteria. A spec with no phase decomposition fails the step, surfacing the shape problem as a finding before Ready rather than inventing phases. Added Exit Criterion 6 and a review-history entry.
|
| | |
|
| |
|
|
|
|
| |
Handoffs that arrive mid-session used to sit unseen until the next startup or a manual check. Today's burst of cross-project handoffs made that gap obvious. I added monitor-inbox.org, the cadence-and-decision layer over process-inbox: check the inbox at every task boundary, decide act-now (just do it) versus file (ask, with filing as option 1), and reply to the sender. An opt-in background-monitor /loop recipe covers unattended watching.
inbox-status (with bats tests) is the cheap check the cadence calls. It lists unprocessed handoffs and exits nonzero when any are pending, using the same artifact exclusions as the wrap-up sanity check. protocols.org gets a short cadence note so the habit fires every session, and INDEX.org lists the new workflow. The act-vs-file rule (act-now is silent, filing asks with file as option 1, ambiguity asks) is the decision protocol we settled today.
|
| |
|
|
| |
An org-drill session asked to send a follow-up email first claimed it couldn't, then hand-built MIME through msmtp, because nothing told it cmail send exists. I added a "Sending Email" subsection to protocols.org (read every session): cmail (c@cjennings.net) is the default for personal mail, dmail for work, and cmail-action send is the tool, with one-liner examples for body-file, attachments, Cc/Bcc, and threaded replies. I also rewrote send-email.org Step 4, replacing the inline-Python heredoc that taught the hard way with the cmail-action send call.
|
| |
|
|
| |
cmail-action send couldn't do a proper reply (no Cc/Bcc, no In-Reply-To/References), so an org-drill session that needed to reply to an upstream maintainer hand-rolled a raw MIME message through msmtp instead. I extended build_message (the pure function) with cc, bcc, in_reply_to, and references, wired the matching --cc/--bcc (repeatable), --in-reply-to, and --references flags through cmd_send, and wrote the tests first. send_message derives recipients from the To/Cc/Bcc headers and strips Bcc, so no manual recipient list is needed.
|
| |
|
|
|
|
| |
A single .ai/session-context.org races when two agents share a project: each agent's writes clobber the other's session log. I added .ai/scripts/session-context-path, which resolves the active path from AI_AGENT_ID: unset gives the legacy .ai/session-context.org singleton (so every existing one-agent session is unchanged), set gives .ai/session-context.d/<id>.org with the id sanitized to filename-safe characters. This is Codex's Phase 1 slice from the runtime-neutral spec: the race fix on its own, no broader refactor.
startup.org's existence check and wrap-it-up.org's rename now resolve through the helper, each with a singleton fallback so older checkouts that haven't synced the script still work. Wrap folds the agent id into the archive name so two agents wrapping in the same minute don't collide. protocols.org documents the rule. Verified with 5 bats cases and a two-agent simulation showing distinct paths per id.
|
| |
|
|
|
|
| |
From jr-estate's handoff: Phase A's =rsync -a --delete= copies the rulesets working tree by disk presence, so a downstream session that starts while rulesets has in-flight WIP pulls that WIP into its own =.ai/workflows/= and =.ai/scripts/=, where it reads as drift the user never authored. I guarded the three rsyncs behind a =git status --porcelain= check on the synced source paths (=claude-templates/.ai/{protocols.org,workflows/,scripts/}=). It syncs when those are clean and skips with a message when dirty, catching up on the next clean session. The check is scoped to those paths, so unrelated rulesets dirt (a stray session-context.org, scratch files) doesn't block the sync.
The handoff's secondary anomaly (two workflow files that didn't reach jr-estate) was a timeline artifact, not a Phase A bug. Both were added in 664bf01 on 2026-05-29, after jr-estate's rsync had already run, so they correctly didn't exist to copy yet.
|
| |
|
|
|
|
| |
org-lint reads an =** Foo= verbatim span in body prose as a possible misplaced heading, but verbatim markup is never a real heading. lint-org kept surfacing these as judgment items, so they recurred in lint-followups.org on every wrap and could never be acted on, since the todo.org content was already correct.
I added lo--verbatim-asterisk-at-line-p, which mirrors the markdown-bold detector: it checks the reported line and the one before it, since org-lint marks the blank line after the offender. A match is now suppressed silently, the same way the cj-comment false positives already are. I flipped the two tests that pinned the old judgment behavior, and confirmed todo.org lints clean (judgment=0). This resolves the checker-bug report I filed in the inbox earlier, which I removed.
|
| | |
|
| |
|
|
|
|
|
|
| |
Health ran the new leakage check on a 43-card deck and hit two false-positive classes. The check read the whole card body, so a =Source: <label> — <url>= citation line inflated the front/back overlap whenever the URL slug repeated the question's words. Range/category cards ("What are the HbA1c ranges across normal, prediabetes, and diabetes?") tripped it too, because the question's categories echo in the answer even though the recalled content is the numbers.
drill-deck-stats.py now routes leakage through an is_leaky helper. It strips =Source:= and created-date lines before computing overlap, and exempts a card when the answer carries a numeric range or threshold the question lacks. leakage_ratio itself is unchanged, so the genuine-restatement case still flags.
Two body conventions now hold: a =Source:= citation goes at the end of a card after two blank lines, and no created/added date goes on a card. drill-to-anki.py now strips =Created:= / =:CREATED:= lines from the back as a backstop, and the workflow's Phase C removes them from the source during the rewrite. I added tests for the source-strip, the numeric carve-out, and the created-line strip, and documented all of it in drill-deck-review.org.
|
| |
|
|
|
|
| |
From health's handoff: the startup =.ai/scripts/= sync was dragging pytest build artifacts into every consuming project. =rsync -a= copies by disk presence, not git status, so the =__pycache__/= and =.pytest_cache/= that rulesets' own pytest leaves in =claude-templates/.ai/scripts/tests/= rode along to each project's tree even though the root =.gitignore= already keeps them out of rulesets' commits. Phase A's scripts rsync now excludes =__pycache__=, =.pytest_cache=, and =*.pyc=. A project that already received the cache has to remove it once by hand, since =--delete= leaves excluded paths in place. I noted that in the startup doc.
Health also flagged that =inbox-send.py= kept needing a manual chmod. The cause wasn't rsync dropping the bit. Four shebang scripts (=inbox-send.py=, =cj-scan.py=, =cj-remove-block.py=, =eml-view-and-extract-attachments.py=) were committed mode 100644, so rsync faithfully copied the wrong mode. I set the exec bit on all four so the synced copies are runnable.
|
| | |
|
| |
|
|
|
|
|
|
| |
I researched spaced-repetition best practices (Wozniak's twenty rules, Matuschak's prompt-writing guide, Nielsen, the Anki and FSRS docs) and folded the findings into the drill-deck pipeline.
drill-deck-stats.py now checks authoring quality on top of structure. Two checks block: answer leakage (a question that echoes >= 80% of its own answer's content words tests recognition, not recall) and duplicate / near-duplicate fronts (confusable cards interfere). Three checks warn without blocking, surfacing rewrite candidates without failing the gate: overloaded backs, list-shaped backs, and binary yes/no prompts. The fuzzy thresholds live in constants at the top of the script, so a real deck that trips false positives can be tuned. I pulled the card-parsing into a parse_cards helper that captures each card's body, and added focused tests for every new helper plus CLI coverage of the leaky, duplicate, and notes-only cases.
drill-deck-review.org gains a Card Authoring Principles section (the why behind the canonical shapes, with sources), a person-card splitting path bounded by the :ID:-preservation rule, a Phase B cost-benefit-removal and leech-reformulation disposition, and a scheduling-is-Anki-side note so a future editor doesn't try to encode FSRS retention in the org source. I left out cloze cards (would need a second note type), per-card tractability targeting and retention encoding (Anki-side telemetry that never reaches the source), and on-face source-stamping (the converter strips those drawers by design). Each is noted with its reason.
|
| | |
|
| |
|
|
|
|
|
|
| |
I backfilled the gaps left after the flashcard work landed. drill-to-anki.py had tests only for its two default helpers. I added coverage for the core parser and its pieces: parse (section-to-tag mapping, drawer-only body, blank trimming, multiline join, no-card input), strip_org_metadata (drawer and planning-line stripping, unclosed drawer), section_to_tag, escape_html, and the deterministic stable_id. I also filled the remaining drill-deck-stats / drill-deck-diff-ids branches (missing-title and PROPERTIES-mismatch warnings, the appeared-IDs note path).
I added test_cross_project_broadcast.py for the two scripts that had none here: is_broadcastable / discover (SEARCH_ROOTS pointed at a tmp tree) / sender_project / inbox_send_path, plus an ERT suite for daily-prep-agenda.el (dp-iso-date, dp-bucket with the clock pinned, dp-format-entry, and dp-collect end to end on a temp org file).
daily-prep-agenda.el needed one change to be loadable under ERT: its batch entrypoint fired on any load. I gated it behind dp--cli-invocation-p, the same readable-files check lint-org.el already uses, so requiring the file for tests no longer runs the extractor. A real invocation with a file argument still fires. A no-argument run now no-ops instead of printing an empty header.
|
| |
|
|
|
|
| |
I incorporated the flashcard-tooling bundle from the work project's deck-review workflow, validated there against a 93-card deck. Three scripts now live under .ai/scripts/: drill-deck-stats.py (pre-rewrite inventory plus a gate that warns on stray *** Answer headers, missing :ID:, non-prompt headings, and #+TITLE jargon like "org-drill"), drill-deck-diff-ids.py (SRS-state preservation check that flags any :ID: lost across a rewrite), and drill-deck-sync (bash wrapper chaining stats, optional diff-ids, then drill-to-anki, writing to ~/sync/phone/anki/ only when the gates pass).
The drill-deck-review.org workflow gains a Helper Scripts section and references the scripts from its phases. I reconciled its output-path prose with the drill-to-anki default that just moved to ~/sync/phone/anki/, so it no longer claims the script still defaults to ~/sync/org/drill/. I added tests for both Python scripts (pure logic plus CLI gate behavior) and a bats suite for the wrapper's guard paths. The clean end-to-end sync path stays uncovered since it needs uv-resolved genanki.
|
| |
|
|
|
|
| |
Two default-behavior tweaks from real use. Output now defaults to ~/sync/phone/anki/ instead of ~/sync/org/drill/. The .apkg is a mobile-Anki artifact the phone picks up from its sync dir, while the org source stays in the project. Deck name now defaults to the raw input basename, case preserved. That drops the #+TITLE preference, which leaked tool-name jargon like "DeepSat org-drill flashcards" into the Anki deck list.
The --deck and --output flags still override both. I dropped the now-unused title_from_org helper and added a test covering the two defaults. genanki is stubbed in the test since uv resolves it only at runtime.
|
| | |
|
| |
|
|
|
|
|
|
| |
I added a drill-deck-review workflow that walks an org-drill deck end-to-end: question-form audit on every heading (so the heading is the prompt, not the answer), content-accuracy audit via subagent against project source-of-truth, source rewrite preserving SRS state, regenerate to ~/sync/phone/anki/. The workflow covers three card families (acronym/concept, person, talking-point) and codifies the person-card pattern as "Who is X? Tell me about their Y." where X is a role descriptor that doesn't name the person and Y is the topical anchor from the answer body.
The drill-to-anki.py script picks up a new strip_org_metadata helper that drops :PROPERTIES: drawers and SCHEDULED/DEADLINE/CLOSED planning lines from the rendered Anki back. Org-drill needs both in the source for SRS state and review scheduling; Anki cards shouldn't show them.
INDEX entry under "On-demand utilities" wires the trigger phrases.
|
| |
|
|
|
|
|
|
| |
git mv in the prior wrap-up commit (0237465) renamed the index
entry without re-staging the disk content, so the archive landed
with an empty Active Goal and missing Decisions, Findings, Files
Modified, and Next Steps sections. This follow-up commits the
populated Summary that was already on disk at wrap-up time.
|
| |
|
|
|
|
|
| |
Multi-arc session: no-approvals batch, codex backlog triage,
page-signal + broadcast infra, voice profile Phase 1 + Phase 2
with SKILL.md split, process-inbox formalization, wrap-it-up
inbox sanity check.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The inbox sanity check I added in 8424e8f counted lint-followups.org
as unprocessed, which surfaced as a false alarm during this session's
wrap-up. lint-org writes its judgment items into inbox/lint-followups.org
earlier in the same wrap-up workflow by design. The file is a
pipeline artifact for the next morning's daily-prep, not a handoff
that needs the value gate.
The find filter now excludes .gitkeep, lint-followups.org, and
PROCESSED-* prefixes. The Validation Checklist line names the same
expected-artifacts list explicitly.
Smoke test: post-fix count is 0 in the rulesets project (where
lint-org just wrote 5 judgment items into inbox/lint-followups.org).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Adds one bullet to When NOT to Use and a new Cadence Guideline
section that names the per-commit-broadcast anti-pattern explicitly.
The new section lays out the five reasons broadcasts stay
capability-and-rule-level rather than commit-level: cost per
broadcast across the fleet, signal-to-noise on project-internal
commits, the rsync-already-does-the-work observation, aggregation
winning over per-commit pings, and the train-projects-to-ignore-inbox
risk.
The end-of-session bundling guidance lands too. If a session ships
several broadcastable changes, bundle them into one broadcast at
session end instead of firing one per commit.
Source: session-end conversation 2026-05-29 surveying today's
cross-project changes. Today's session shipped 13 cross-project
items (4 new workflows, 6 workflow updates, 2 new scripts, 1 new
bin tool). A per-commit broadcast cadence would have fired 13 inbox
files across 23 targets, or 299 total inbox files. One consolidated
broadcast (or no broadcast at all, since Craig already coordinated
manually) covered the same ground.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Wrap-up never knew about the inbox. After process-inbox.org landed
today as the formal workflow for handoff intake, wrap-it-up.org
needs to surface inbox/ when it's non-empty so the wrap doesn't
silently defer handoffs to next session.
This commit adds a new Inbox sanity check sub-step under Step 3
(project hygiene). The check runs find inbox -maxdepth 1 -type f
filtered to skip .gitkeep and PROCESSED-* prefixes. A non-zero
count surfaces with the file list and a recommendation to run
process-inbox.org or explicitly defer each item. A zero count or no
inbox/ directory makes the check a silent no-op.
It also adds one line to the Validation Checklist: inbox is empty
(excluding .gitkeep and PROCESSED-* prefixes), OR each remaining
item has an explicit deferral logged in the valediction.
This is the only integration gap surfaced today. The other gaps
considered (LAST_INBOX_PROCESS marker stamp, sync-check, make
status) didn't justify wrap-up changes. The marker is
process-inbox's own responsibility. sync-check is project-specific
to rulesets. make status doesn't generalize across projects.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit is end-of-day housekeeping for the rulesets session that
ran 2026-05-28 through 2026-05-29.
mcp/servers.json gains the signal-mcp stdio entry pointing at the
locally-cloned rymurr/signal-mcp install at ~/.local/share/signal-mcp/.
The entry uses Craig's primary +15103169357 as --user-id, which will
need updating to the Google Voice number once that signal-cli
registration lands (TODO scheduled today). The configuration is
staged but not registered. The make install-mcp pipeline was
interrupted earlier by the GPG pinentry (Craig on vacation, away
from desk). Running make install-mcp at the desktop with the GPG
passphrase will complete the registration.
.ai/session-context.org captures the live session narrative covering
the no-approvals batch (6 :quick:solo: TODOs), the codex backlog
triage, the page-signal infra, the voice profile Phase 1 plus Phase
2, the SKILL.md / voice-profile.org structural split, and the inbox
processing pass. No wrap-up performed. The session-context stays
under that name pending the wrap-it-up workflow when Craig is back
at the desk.
The substantive work in this session shipped across many prior
commits, each with its own focused message.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
clear processed inbox
The process-inbox workflow walked the four inbox arrivals (one from
home, one from jr-estate, two from health):
- 2026-05-28-0858 home spec-naming-convention: implemented in
bb28cfa. Deleted.
- 2026-05-29-0832 jr-estate startup-rsync-carried-dirty: filed as
[#B] :feature: TODO under Rulesets Open Work. Three options
captured (skip-when-dirty, clean-files-only, clean-ref-based) with
my recommendation noted. Deleted.
- 2026-05-29-1111 health org-drill-anki initial: superseded by 1114.
Deleted without filing.
- 2026-05-29-1114 health org-drill-anki updated: implemented in
506ab6e. Deleted.
The startup-rsync-dirty TODO also captures an anomaly the jr-estate
handoff flagged: even with --delete, two files that DO exist in
rulesets canonical (cross-project-broadcast.org, page-signal.org)
did NOT propagate. This is likely a timing issue (those files were
added after the jr-estate Phase A rsync ran). The anomaly is worth
confirming when the TODO is picked up.
notes.org Workflow State stamped :LAST_INBOX_PROCESS: 2026-05-29.
Inbox now empty.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Generalizes the health-drill-to-anki.py converter into a template
script under claude-templates/.ai/scripts/. Every project's startup
rsync now picks it up at .ai/scripts/drill-to-anki.py.
The converter walks an org-drill file. Top-level * Section headings
become Anki tags. Each ** Card name :drill: entry becomes a card
with the heading as Front and the body as Back (newlines converted
to <br>).
Parameterized from the original health-specific version:
- Input file is a positional argument (was hardcoded
health-drill.org).
- Deck name defaults to the org file's #+TITLE if present, else the
input basename in Title Case (was hardcoded "Health Drill").
- Output path defaults to ~/sync/org/drill/<input-basename>.apkg
(was hardcoded health-drill.apkg in the same dir).
- Deck and model IDs are derived from the deck name via SHA-256, so
re-running against the same source produces stable IDs. Anki
imports update existing cards in place rather than duplicating.
Dependencies via PEP 723 inline script metadata. The shebang is
#!/usr/bin/env -S uv run --script. First run resolves and caches
genanki>=0.13. Subsequent runs are instant. There is no venv to
maintain and no PEP 668 friction.
Smoke tested against ~/projects/health/health-drill.org. The script
wrote 43 cards into the Health Drill deck, matching the original
script's output.
Inbox source: 2026-05-29-1114-from-health-todo-b-org-drill-anki-export-updated.org.
Craig confirmed all projects will likely have org-drill files,
justifying template-tier promotion.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Both workflows now check that the file under review (or the spec
being responded to) ends with -spec.org before proceeding. If it does
not, the workflow stops and surfaces the mismatch with the rename
suggestion.
The suffix is the identifier per Craig's spec-naming convention:
every design, decision, or planning document under a project's docs/
directory ends with -spec.org. The .org extension alone is not enough
because docs/ holds non-spec org files too (tutorials, frozen
inventories, reference material).
spec-review.org gained a top-level Precondition section between When
to Use and Approach. spec-response.org gained the same Precondition
section in the parallel position, with a note that the review-file
convention <spec-basename>-review.org means a misnamed spec produces
a mis-pointed review file too.
Inbox source: 2026-05-28-0858-from-home-spec-naming-convention-apply-to-spec.org.
Home renamed two docs to the new convention and asked rulesets to
update the template workflows so the next startup rsync in every
project picks up the guard.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
helper
Three coupled additions ship together.
claude-templates/bin/page-signal is a bash wrapper around signal-cli
send. It defaults to --note-to-self for safety. The wrapper supports
--file for attachments, --to <+number> for outbound (explicit per
call, no defaults, no batch), --quiet, and --json. Exit codes: 0
sent, 1 signal-cli failure, 2 usage error, 3 signal-cli not
installed.
claude-templates/.ai/workflows/page-signal.org carries the
discrimination rules and safety rails. When desktop notify covers it,
don't reach for Signal. Long-running task completion is the canonical
case. Outbound to other contacts requires explicit Craig instruction
per send. A known-limitation note covers the current notification
gap. signal-cli registered on Craig's primary number means messages
don't fire notifications until the pending Google Voice registration
lands.
claude-templates/.ai/workflows/cross-project-broadcast.org and its
helper cross-project-broadcast.py fan out a single message file to
every AI project's inbox in one operation. Discovery is
fingerprint-based: any directory under ~/code, ~/projects, ~/.emacs.d
with both .ai/protocols.org and a top-level inbox/ is broadcastable.
Senders are auto-excluded. Verified discovery against 23
broadcastable targets.
Makefile's install target gains a general bin/ loop. The previous
version hardcoded bin/ai. The new version iterates over every
executable under claude-templates/bin/ and symlinks each into
~/.local/bin/. install-hooks (existing Claude hook installer) is
unchanged. install-githooks (sync-check pre-commit hook setup, added
earlier today) is unchanged. The bin/ loop now picks up bin/page-signal
automatically.
INDEX entries for both new workflows landed under Tools and meta.
No bats tests on the new scripts. page-signal was smoke-tested with a
live send. The send succeeded. The notification gap is covered by the
workflow's known-limitation note. cross-project-broadcast.py was
smoke-tested via --list against the live project set. Tests can be
added when the broadcast pattern proves out across multiple use cases.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
open-tasks.org Phase A now runs `emacs --batch -q -l
.ai/scripts/todo-cleanup.el --archive-done todo.org` as a pre-step
before the parallel read batch. A level-2 task that completed during
the session sits as ** DONE under Open Work until something archives
it, which means Next Mode would surface it as a "what's next" candidate
between cleanups. The pre-step ensures Phase A's read of todo.org
reflects current state.
The pre-step skips only in an explicit read-only or dry-run context.
Default is always to sweep.
Common Mistake #13 records "recommending a freshly-DONE task" with the
pointer back to the pre-step.
The proposal came from a pearl handoff on 2026-05-28.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Generic process-inbox workflow at claude-templates/.ai/workflows/ and
mirror. Owns inbox discipline across every project: items are ideas to
evaluate, not orders to execute, and earn a place in todo.org or git
history only when they pass a three-question value gate.
The gate (Phase B):
- Advances an existing TODO (look up by topic).
- Improves how the project works (architecture, workflows, tooling,
rule hygiene).
- Serves the project's stated mission (read from notes.org
Project-Specific Context).
One yes accepts. Three nos reject.
Per-source rejection flow (Phase D):
- From Craig: state in chat, wait for override.
- From another project: write a response via inbox-send naming which
gate question failed plus any reconsideration condition. Silent
rejection on a handoff is worse than no reply.
- From a script or automated system: just delete.
Phase B.1 gates filing on priority-scheme presence. If todo.org has a
scheme at the top, file with cookie + mandatory type tag + optional
effort/autonomy tags. If not, surface a one-sentence nudge to adopt
one (or to skip grading and flag the gap in the commit).
Phase D within accepts splits implement-now / fold-into-existing /
file-as-TODO so the inbox doesn't default to inflating todo.org for
every item that passes the gate.
Phase E stamps :LAST_INBOX_PROCESS: in notes.org Workflow State if the
section exists.
startup.org Phase C step 2 now delegates here instead of inlining the
inbox-processing language. INDEX entry under Tasks and planning lists
the full set of trigger phrases.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Pearl independently built its own no-approvals workflow (handoff in this
morning's inbox) and asked rulesets to take the best from both. That's
cross-project signal that the workflow earns a place at the template tier.
Promoted from =.ai/project-workflows/= to =claude-templates/.ai/workflows/=
with a mirror under =.ai/workflows/=. INDEX entry added under "Tools and
meta" listing the full set of trigger phrases.
Merged from pearl's draft: the prominent "What's Suspended" / "What Stays
On" split (same content as the prior "Contract" section, easier to scan),
wider trigger phrases (the project-only version had fewer), the
mode-resets-when-Craig-switches-topics guard, an explicit destructive-action
carve-out as its own bullet rather than buried in the "real question"
section, and a subagent-review-gate callout.
Kept from the rulesets version: the Session Log update emphasis between
items, the real-question include/exclude lists, and the don't-auto-wrap-up
guard.
A History section at the bottom records the merge for future archaeology.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
All 16 open tasks bucketed and updated. 14 received autonomous Phase C
edits (13 type-tag additions per the new scheme plus #15's body refresh
for the accumulating pearl signal). Phase D adjudicated two priority
bumps and the morning's inbox spillover. Phase E stamped :LAST_AUDIT:
in notes.org Workflow State.
Autonomous Phase C:
- Tagged tasks 1-11 and 13-14 with their type tag (:feature:, :chore:,
:spec:), bumped LAST_REVIEWED to 2026-05-28. Tasks 12, 15, 16 already
carried type tags.
- Refreshed task #15 body to reference the four pearl pattern-catalog
notes now in docs/design/ (six worked patterns total).
Phase D adjudication:
- #15 (cross-project pattern catalog) bumped [#C] to [#B]. Pearl shipped
6 worked examples plus a synthesizing principle and is asking for
spec-review iterations. Design questions still open but evidence is
past the tipping point.
- Filed new [#B] :feature: TODO for the codex Phase 1 race-fix
(AI_AGENT_ID + session-context.d/<id>.org), lifted from the broader
runtime spec (#16). Phase 1 alone is low-risk and fixes a real
correctness issue under simultaneous agents.
Pearl intake (4 inbox files from this morning):
- Moved 0155 (patterns 4-5) and 0303 (pattern 6) into docs/design/
alongside the prior two pattern-catalog notes. Referenced from #15.
- Filed new [#C] :chore:quick:solo: TODO for pearl 0138's
--archive-done sweep at the start of open-tasks.org Phase A.
- Filed new [#C] :feature:solo: TODO for pearl 0226's spec-review.org
Phase 6 implementation-task enumeration.
- Deleted 0124. Already implemented this session as the audit-warranted
pre-step plus the LAST_AUDIT stamp now live in the workflow files.
|