<feed xmlns='http://www.w3.org/2005/Atom'>
<title>rulesets/.ai/workflows/wrap-it-up.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-21T03:28:37+00:00</updated>
<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>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>
<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>feat(workflows): wrap-up promotes to the KB and records the usage receipt</title>
<updated>2026-06-10T23:18:31+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-10T23:18:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=242b95ea44d4ba12a611a0b2acb3edc109ce74f5'/>
<id>urn:sha1:242b95ea44d4ba12a611a0b2acb3edc109ce74f5</id>
<content type='text'>
Phase 3 of the agent KB spec. Step 1 of wrap-it-up gains a promotion check against knowledge-base.md's inclusion criteria, and every Summary now ends with a "KB: promoted N / consulted yes-no" line — the single grep-able input to the spec's 30-day success-metrics checkpoint. The validation checklist enforces the line.
</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>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(wrap-it-up): inbox sanity check exempts lint-followups.org</title>
<updated>2026-05-30T01:49:47+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-30T01:49:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=efd30620b001f0481ff802f7497907cb3da9463d'/>
<id>urn:sha1:efd30620b001f0481ff802f7497907cb3da9463d</id>
<content type='text'>
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).
</content>
</entry>
<entry>
<title>docs(wrap-it-up): add inbox sanity check + checklist line</title>
<updated>2026-05-30T01:13:04+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-30T01:13:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=8424e8ff33fd397483bf695b56ae229575f0c067'/>
<id>urn:sha1:8424e8ff33fd397483bf695b56ae229575f0c067</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>docs(workflows): document GitHub-family assumption in wrap-it-up Step 3.5</title>
<updated>2026-05-22T18:44:11+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-22T18:44:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=a785f54eb4f8e45f97be737047eb5a4547a5dd5a'/>
<id>urn:sha1:a785f54eb4f8e45f97be737047eb5a4547a5dd5a</id>
<content type='text'>
Step 3.5's Linear ticket-state sweep uses gh to find the merged PR for a Dev-Review ticket, which assumes a GitHub-family host. That holds today because DeepSat, the only Linear-using project, lives on GHE where gh talks to the API.

I added a note flagging the assumption rather than rewriting the step to be provider-agnostic. A future Linear project on GitLab, Gitea, or Bitbucket would need a different PR lookup, but none exists yet, so documenting the boundary beats building for a host we don't have.
</content>
</entry>
<entry>
<title>docs(workflows): swap wrap-up date-coverage scan for task-review health check</title>
<updated>2026-05-20T17:41:13+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-20T17:41:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=3627d5e61e2adc8cd196958f62579fcdf9d20889'/>
<id>urn:sha1:3627d5e61e2adc8cd196958f62579fcdf9d20889</id>
<content type='text'>
The date-coverage scan flagged every open [#A]/[#B] task with no DEADLINE or SCHEDULED, on the assumption that high-priority work needs a date. That assumption is wrong (research and watch-list tasks are legitimately dateless), so the scan generated dismiss-or-paper-over cleanup at every wrap-up.

The replacement watches the daily task-review habit instead. It calls task-review-staleness.sh todo.org 30 and, when the count is non-zero, writes one summary line to the follow-ups file: N top-level tasks unreviewed for &gt;30 days. There's no per-task dump, because the per-task walk is the review habit's job. Staleness, not datelessness, is the signal worth surfacing.

The change lands in both the canonical workflow and the project mirror.
</content>
</entry>
</feed>
