<feed xmlns='http://www.w3.org/2005/Atom'>
<title>rulesets/claude-templates/.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-07-09T19:02:39+00:00</updated>
<entry>
<title>chore: drop AI co-author from generated-document headers</title>
<updated>2026-07-09T19:02:39+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-09T19:02:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=6def7c4d63f499aba10fe93c7bb2c7e206a7d7f5'/>
<id>urn:sha1:6def7c4d63f499aba10fe93c7bb2c7e206a7d7f5</id>
<content type='text'>
Every org document an agent writes carried `#+AUTHOR: Craig Jennings &amp; 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.
</content>
</entry>
<entry>
<title>fix(startup): skip the .ai/ template sync when the project branch is behind</title>
<updated>2026-07-04T17:53:18+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-04T17:53:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=bc4befa139781801b41231ef1b0d3be8939d04a1'/>
<id>urn:sha1:bc4befa139781801b41231ef1b0d3be8939d04a1</id>
<content type='text'>
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&gt;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.
</content>
</entry>
<entry>
<title>feat(sync): never let untracked or gitignored files block template updates</title>
<updated>2026-07-02T09:22:09+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-02T09:22:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=ed75d3c17e7605d2669456b53a03def531a607b7'/>
<id>urn:sha1:ed75d3c17e7605d2669456b53a03def531a607b7</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>feat(rules): add the host-identity guard rule and startup probe</title>
<updated>2026-07-02T09:19:01+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-02T09:19:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=b6a977cec25fddf1e498896cec3ad9462fc149db'/>
<id>urn:sha1:b6a977cec25fddf1e498896cec3ad9462fc149db</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>feat(startup): add the spec-sort nudge; notify .emacs.d the convention is live</title>
<updated>2026-07-02T04:24:26+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-02T04:24:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=21639cb395bd363f9406694adebd9a3675bf1096'/>
<id>urn:sha1:21639cb395bd363f9406694adebd9a3675bf1096</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>feat(inbox): consolidate three inbox workflows into one engine</title>
<updated>2026-06-24T03:06:46+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-24T03:06:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=24ca58d764dbcc2bad57a914a10e9e9b89a3f66e'/>
<id>urn:sha1:24ca58d764dbcc2bad57a914a10e9e9b89a3f66e</id>
<content type='text'>
I merged process-inbox, monitor-inbox, and inbox-zero into one inbox.org engine. A shared core (value gate, skeptical review, disposition ladder, reply discipline, capture-guard, priority-scheme check) holds the logic that used to be duplicated and cross-referenced across the three files. Each mode (process, monitor, roam) references the core by name instead of restating it.

Every trigger phrase still works, now routing to a mode, so there's nothing to relearn. I added the interactive auto inbox zero mode: ask for an interval, run roam mode on /loop, acknowledge-only on an empty cycle, surface a find to a queue gated on a yes. The fully-unattended /schedule pass stays vNext, tracked separately.

I repointed every live caller (INDEX, protocols, startup Phase C, wrap-up Step 3, triage-intake, broadcast) at inbox.org and its modes, then deleted the three old files. triage-intake and no-approvals stay separate by design. The value gate, dispositions, capture-guard, and reply discipline all behave as before.

Built from the Ready spec. Workflow-integrity and sync-check pass on both the canonical and mirror trees, the stale-reference grep is clean, and the full suite is green.

Claude-Session: https://claude.ai/code/session_017PtX1nt1rtYVATuzmzBS4f
</content>
</entry>
<entry>
<title>feat(kb): wire consult + contribute KB prompts into the workflows</title>
<updated>2026-06-21T03:28:37+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-21T03:28:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=76e55591e2a66e8ef42ee6e4535882545ee3d33b'/>
<id>urn:sha1:76e55591e2a66e8ef42ee6e4535882545ee3d33b</id>
<content type='text'>
Recent session receipts read "promoted 0 / consulted no" across the board: the wrap-up KB-promotion check existed but fired too late, and nothing surfaced existing lessons to read. This adds the spec's four light prompts plus the read-side step it was missing. Startup gets two Phase C nudges (gated on the roam clone): a consult line listing project-relevant node titles, and a contribute line pointing at the best-practices node. Triage-intake and inbox-zero get a conditional end-of-flow capture reminder that fires only on real signal. Wrap-up gets an early reflection prompt at the top of Step 1 that feeds the existing receipt, so learnings are captured while fresh instead of reconstructed after the Summary. Ratifies the spec's five decisions and adds D6 (the read-side surfacing).
</content>
</entry>
<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>
</feed>
