<feed xmlns='http://www.w3.org/2005/Atom'>
<title>rulesets/.ai/workflows/startup.org, 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>feat(workflows): add inbox-zero for routing the roam inbox by project</title>
<updated>2026-06-13T18:23:18+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-13T18:23:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=651b65e25c2dd13a5a371f1de91e17a41d906a84'/>
<id>urn:sha1:651b65e25c2dd13a5a371f1de91e17a41d906a84</id>
<content type='text'>
The global roam inbox (~/org/roam/inbox.org) is one shared capture file every project can see, and nothing routed its items to the project that owns them. inbox-zero claims the items prefixed for the current project, files them into that project's todo.org per the process-inbox discipline, and removes them from the shared inbox. Foreign-prefixed and unowned items stay. Every scan reports the total item count plus how many appear related to this project.

This v1 is single-destination: it routes by explicit &lt;project&gt;: prefix only. The domain-aware mode that would guess every item's owner and empty the whole inbox in one run is deferred until the multi-project need is concrete.

Wired into both session ends so each project touches the inbox twice a session: startup surfaces a read-only count and offer, wrap-up Step 3 sweeps the claimed set before the cleanup scripts so imported tasks ride the wrap commit. INDEX carries the trigger phrases.
</content>
</entry>
<entry>
<title>fix(install): link default hooks in make install</title>
<updated>2026-06-11T16:32:40+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-11T16:32:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=d576fc217ba304b48dfb1c54b92bc1849397fd9b'/>
<id>urn:sha1:d576fc217ba304b48dfb1c54b92bc1849397fd9b</id>
<content type='text'>
session-clear-resume.sh shipped 2026-06-02 with its settings.json entry, but make install didn't cover hooks and nothing re-ran install-hooks, so the symlink only existed on machines that had linked it by hand. Everywhere else the hook errored silently on every /clear.

make install now links DEFAULT_HOOKS alongside skills, rules, config, and bin scripts, so the startup workflow's install step propagates new hooks machine-wide. Opt-in hooks stay manual. scripts/tests/install-hooks-link.bats covers the new section. The SessionStart-on-clear todo task closes with this: the hook feature already existed, and the gap was distribution.
</content>
</entry>
<entry>
<title>feat(startup): run make install in Phase A.0 to link new skills</title>
<updated>2026-06-05T05:28:31+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-05T05:28:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=3eed2895b2d23d1d8e468aee6f3dfd8122012fe4'/>
<id>urn:sha1:3eed2895b2d23d1d8e468aee6f3dfd8122012fe4</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>fix(workflows): commit template-sync churn deterministically</title>
<updated>2026-05-31T23:15:03+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-31T23:15:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=18f6c4c877940d740406b859f61a540fc48f13f5'/>
<id>urn:sha1:18f6c4c877940d740406b859f61a540fc48f13f5</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>refactor(workflows): restructure startup and triage-intake into reading lanes</title>
<updated>2026-05-31T16:31:44+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-31T16:31:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=3640664e0fa11d7eb99c2900df57734b411e2d2b'/>
<id>urn:sha1:3640664e0fa11d7eb99c2900df57734b411e2d2b</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>feat(session-context): resolve the active path per AI_AGENT_ID</title>
<updated>2026-05-31T02:48:13+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-31T02:48:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=143feda0644d2289954b694f3ce4cee2fc74b808'/>
<id>urn:sha1:143feda0644d2289954b694f3ce4cee2fc74b808</id>
<content type='text'>
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/&lt;id&gt;.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.
</content>
</entry>
<entry>
<title>fix(startup): skip the .ai/ template sync when rulesets has uncommitted WIP</title>
<updated>2026-05-31T02:41:06+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-31T02:41:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=9a1bea9bfc066312bf9743dc23c88f191a36cc16'/>
<id>urn:sha1:9a1bea9bfc066312bf9743dc23c88f191a36cc16</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>fix(startup): exclude Python cache from script sync and restore script exec bits</title>
<updated>2026-05-30T19:18:44+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-30T19:18:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=968a39bb3978e6ad499447ce173e2265dee772a2'/>
<id>urn:sha1:968a39bb3978e6ad499447ce173e2265dee772a2</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>feat(workflows): add process-inbox.org with value-gate discipline</title>
<updated>2026-05-28T13:56:24+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-28T13:56:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=0c7eb59f813b5572cc32beb6d2dd09355639cbfc'/>
<id>urn:sha1:0c7eb59f813b5572cc32beb6d2dd09355639cbfc</id>
<content type='text'>
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.
</content>
</entry>
</feed>
