<feed xmlns='http://www.w3.org/2005/Atom'>
<title>rulesets/.ai, branch main</title>
<subtitle>Claude Code skills, rules, and language bundles
</subtitle>
<id>https://git.cjennings.net/rulesets/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/rulesets/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/'/>
<updated>2026-06-17T04:40:42+00:00</updated>
<entry>
<title>refactor: remove unused cross-agent-comms subsystem</title>
<updated>2026-06-17T04:40:42+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-17T04:40:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=e1933fe685a3e15d001552537df90e33ba00b83a'/>
<id>urn:sha1:e1933fe685a3e15d001552537df90e33ba00b83a</id>
<content type='text'>
Nothing used the cross-agent message system (send/recv/watch/status/discover/halt/resume over the inbox/from-agents/ file-IPC protocol). Every cross-project handoff goes through inbox-send instead. I removed the scripts, READMEs, workflow, tests, INDEX entry, the three startup.org wirings, and the legacy bin symlinks, then repointed helper-mode's escalation to inbox-send and noted the removal in the generic-agent-runtime spec.
</content>
</entry>
<entry>
<title>chore: task audit (reconcile open work, demote 2 skill designs)</title>
<updated>2026-06-16T05:06:40+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-16T05:06:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=ab9f79aaf6c2529b61b625455d9c93b8bad1da2b'/>
<id>urn:sha1:ab9f79aaf6c2529b61b625455d9c93b8bad1da2b</id>
<content type='text'>
I reconciled all 11 open tasks against session history and repo state and refreshed their review stamps. I corrected two stale preambles: helper-instance's shipped detection slices, and memories-sync's claim that work was pending when Phases 0-4 had already shipped. The create-documentation and research-writer skill designs drop to [#D]. Both are designed but unbuilt and wait on a real triggering task, so they shouldn't sit at [#C] against active work.
</content>
</entry>
<entry>
<title>chore: process inbox (file fix-speedrun task, clear pearl acks)</title>
<updated>2026-06-16T04:41:57+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-16T04:41:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=4fe184ec364f20a72c5e12a597d2bf99c01ece06'/>
<id>urn:sha1:4fe184ec364f20a72c5e12a597d2bf99c01ece06</id>
<content type='text'>
I filed the .emacs.d "fix speedrun" proposal as a [#C] spec task, with its content preserved in docs/design for spec-create later. The two pearl acks confirmed handoffs I'd already sent, so they needed nothing back.
</content>
</entry>
<entry>
<title>feat(triage): add a per-sweep timestamp to auto mode output</title>
<updated>2026-06-15T23:35:29+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-15T23:35:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=1898a0d85d7da0bf05b4337a11fd1b823b5827fe'/>
<id>urn:sha1:1898a0d85d7da0bf05b4337a11fd1b823b5827fe</id>
<content type='text'>
Auto-mode sweeps now end with the date, time, and timezone on their own final line, so an away reader gauges each summary's freshness at a glance without computing it. The stamp prints on every sweep, including a quiet "no changes" one — there the stamp is the proof the loop ran.

Same-day addendum to the work-project auto-mode proposal.
</content>
</entry>
<entry>
<title>feat(triage): add auto mode for unattended monitoring</title>
<updated>2026-06-15T19:41:00+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-15T19:41:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=561e481c492dc0e160158b8df5c62abbd3530d6b'/>
<id>urn:sha1:561e481c492dc0e160158b8df5c62abbd3530d6b</id>
<content type='text'>
Add an auto mode to the triage-intake engine: a self-running variant for when Craig is away but wants tight awareness. It runs the standard sweep on a short interval (default 20 min) as an in-session loop, accumulates findings instead of mutating state, and gates the mutations behind "close the triage" (flush the batch, keep looping) and "stop the triage" (flush, then stop).

A sweep advances nothing — no sentinel write, no todos, no mail actions, no commit. The scan window grows from the last close to the next, so nothing between sweeps is dropped, and the sentinel still means "everything before this timestamp has been scanned" — it just advances once per close. Each sweep reports deltas plus a running "responses awaiting your acknowledgment" list, the primitive an away user needs that a delta-only sweep loses.

The unacked list is durable in .ai/triage-intake-unacked.org so it survives a crash, a clear, or a restart — the away-from-desk case the mode exists for. Delivery is an in-session loop so MCP auth is inherited; a detached cron schedule stays out of scope and belongs to the morning-ops orchestrator, which can reuse this accumulate behavior as its triage limb.

Source proposal from the work project, design decisions ratified 2026-06-15.
</content>
</entry>
<entry>
<title>feat(inbox): define monitor-inbox as a 15-min loop with clean-tree gates</title>
<updated>2026-06-15T15:36:22+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-15T15:36:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=edb545db727861f21052ca5111db1d949ebf030a'/>
<id>urn:sha1:edb545db727861f21052ca5111db1d949ebf030a</id>
<content type='text'>
Redefine "monitor the inbox" as the explicit behavior Craig wants: run one process-inbox pass now, then loop process-inbox every 15 minutes. The 15-minute loop was previously an opt-in background recipe; it's now the defined meaning of the phrase.

Gate the workflow at both ends on a clean worktree and a green full-suite run. Starting on a dirty tree lets the per-item auto-commit sweep up unrelated changes; starting on a red suite hides whether the monitor broke anything. On a dirty tree, offer to commit in discrete batches; on a red suite, offer to investigate — never start until both are satisfied, and leave the tree clean and green when the loop stops.

Add the no-approvals execute criteria: an accepted item self-applies only when agreed (passed the value gate and Skeptical Review), quick (under ~15 min including verification), and solo (no decision needed from Craig). All three commit and push at the end of the item; miss any and it files or, for shared-asset and convention changes, parks.

Broaden the Skeptical Review to run on every arriving task and file, not only shared-asset proposals — a core right/complete/simpler pass on everything, with the cross-project battery added for changes that sync to consuming projects.
</content>
</entry>
<entry>
<title>chore(ai): archive session record, note helper-instance resume plan</title>
<updated>2026-06-15T13:44:03+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-15T13:44:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=b0503dfe7028af1fab3bfb77b474b1b57c801e7e'/>
<id>urn:sha1:b0503dfe7028af1fab3bfb77b474b1b57c801e7e</id>
<content type='text'>
</content>
</entry>
<entry>
<title>feat(ai): add helper-mode workflow contract</title>
<updated>2026-06-15T13:25:37+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-15T13:25:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=0b681dca75299a81549c78681850f353e6a64a87'/>
<id>urn:sha1:0b681dca75299a81549c78681850f353e6a64a87</id>
<content type='text'>
helper-mode.org is the canonical home of the helper-instance rules: a second Claude alongside a live primary in the same project. It defines the four read/write tiers (always-safe reads and own-context writes, safe-by-discipline scoped single-heading edits, primary-only file-wide passes and all git mutation, escalation), the four data-integrity windows, the light startup, and the helper wrap-up (archive own context file, skip commit, with the git ban lifting only for an orphaned helper that ends up alone).

protocols.org gets a one-paragraph pointer, and INDEX.org gets a triggerless catalog entry like startup.org, so the no-trigger workflow clears the integrity check without a special case.

The contract is the canonical home. The routing that sends a session here (ai --helper, startup's roster branch, the wrap-up helper branch) ships behind the feature's drill gate and isn't live yet. Until then a session adopts it by an explicit "you are a helper" instruction.
</content>
</entry>
<entry>
<title>feat(ai): add agent-roster detection script with tests</title>
<updated>2026-06-15T06:14:46+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-15T06:14:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=f8bdf302fd71ba73ae1424d86275e1e223f09cf3'/>
<id>urn:sha1:f8bdf302fd71ba73ae1424d86275e1e223f09cf3</id>
<content type='text'>
agent-roster is the single detection primitive for concurrent same-project Claude sessions: pgrep -x claude, resolve each pid's cwd from /proc, keep those at or inside the project root, and drop the scanner's own ancestry. It exits 0 when alone, 1 when other agents are present (printed pid + cwd), and 2 when the roster can't run. Both the helper launcher and the in-session startup check will call this rather than re-scanning.

pgrep and /proc are the system boundary, so I made them injectable (ROSTER_PGREP, ROSTER_PROC, ROSTER_SELF_PID) and the bats exercise the real include/exclude logic against fixtures, no agents spawned. The unavailable paths (no /proc, or pgrep absent) report on stderr and exit 2 rather than a false "alone".

This is the first slice of the helper-instance task. Startup and ai --helper wiring follow.
</content>
</entry>
<entry>
<title>docs(ai): require an epoch on the tail of helper-agent ids</title>
<updated>2026-06-15T03:07:00+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-15T03:07:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=e0f914d510c081db45cafaf4fe5c8f7b65e46fec'/>
<id>urn:sha1:e0f914d510c081db45cafaf4fe5c8f7b65e46fec</id>
<content type='text'>
A helper agent's session-context file is .ai/session-context.d/&lt;id&gt;.org. A bare, reused id like "codex" makes the next run resolve to the previous run's leftover anchor, which it then mistakes for a crash to recover or clobbers. That bit on 2026-06-13: a codex run left codex.org for the next session to clean up.

The fix is a convention, not a resolver change. The spawner appends an epoch on the tail (host.project.runtime.&lt;epoch&gt;) so each run gets a fresh anchor. The epoch can't be minted inside session-context-path, since that resolver runs many times per session and must return the same path each call. I documented it in protocols.org, the wrap-up recommended-shape note, and the resolver header.
</content>
</entry>
</feed>
