aboutsummaryrefslogtreecommitdiff
path: root/claude-templates
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-27 10:48:12 -0500
committerCraig Jennings <c@cjennings.net>2026-07-27 10:48:12 -0500
commit6c1ea8bbc3775fe7c481f41b4f30e0c0110a9339 (patch)
treed8607d3c7abaaa901678c89ad4e45cbc1eaca739 /claude-templates
parentf2609d9f9ad33486bef43211d753ba53e1e24181 (diff)
downloadrulesets-6c1ea8bbc3775fe7c481f41b4f30e0c0110a9339.tar.gz
rulesets-6c1ea8bbc3775fe7c481f41b4f30e0c0110a9339.zip
feat: add peer-reasoning contract and fix two silent probe defects
I added a Collaborative Peer Reasoning section to the interaction rules. It governs how an interpretation forms before any rule about presenting choices: infer first and clarify only at material forks, test a conclusion against its strongest alternative, let a correction update the downstream model instead of just the wording. The file's framing line widened to match. Two probes were failing silently. The startup KB nudge looked up the best-practices node by grepping file content for its slug. A roam node's slug lives in its filename, so the lookup always returned empty. The nudge pointed at nothing in every project and every session, for as long as it shipped. It matches the filename now, through find rather than a glob so zsh doesn't abort on no match. The browser rule told agents to open URLs with a form ending in &>/dev/null &. That discards the "Opening in existing browser session." line confirming the tab opened. Warm and cold start now split: foreground and read the confirmation when Chrome is already up, detach only when it isn't. The confirmation is on stdout, verified rather than assumed. I filed two tasks from handoffs. The sentry triage split needs a work-vs-personal classification mechanism before its wording can move, because the current rule excludes by category and category can't express that split. The publish-lock design is approved but carries three open gaps. The load-bearing one is a lock held across an unbounded human approval pause. I also swept the old processed handoffs out of inbox/. History keeps them.
Diffstat (limited to 'claude-templates')
-rw-r--r--claude-templates/.ai/protocols.org16
-rw-r--r--claude-templates/.ai/workflows/startup.org4
2 files changed, 16 insertions, 4 deletions
diff --git a/claude-templates/.ai/protocols.org b/claude-templates/.ai/protocols.org
index 2ea041b..f4eefed 100644
--- a/claude-templates/.ai/protocols.org
+++ b/claude-templates/.ai/protocols.org
@@ -374,9 +374,19 @@ Craig runs a pure Wayland setup (Hyprland) and avoids XWayland/Xorg apps.
- Clipboard: Use =wl-copy= and =wl-paste= (NOT =xclip= or =xsel=)
- Window management: Use Hyprland commands (NOT =xkill=, =xdotool=, etc.)
- Prefer Wayland-native tools over X11 equivalents
-- Open URLs in browser: Use =google-chrome-stable "URL" &>/dev/null &=
- - The =&>/dev/null &= is required to detach the process and suppress output
- - Without it, the command may appear to hang or produce no result
+- Open URLs in browser: invoke Chrome directly — never =xdg-open=, which returned success in a home session on 2026-07-26 while no tab appeared.
+
+ Chrome is normally already running, and in that case it hands the URL to the live session and exits immediately (rc 0), printing =Opening in existing browser session.= on *stdout*. So run it in the foreground and read that line as the confirmation the tab actually opened:
+
+ #+begin_src bash
+ google-chrome-stable --new-tab "URL"
+ #+end_src
+
+ Don't redirect stdout away while checking for that line — verified 2026-07-27 on ratio: with =2>/dev/null= the message still appears (it isn't stderr), and with =>/dev/null= it vanishes.
+
+ Several URLs in one invocation open as separate tabs (=google-chrome-stable --new-tab "URL1" "URL2"=). Pass them as separate words or an array — the Bash tool runs zsh, which does not word-split an unquoted =$urls= variable, so a space-joined string arrives as one malformed argument (see the zsh note below).
+
+ *Cold start.* If Chrome is *not* already running, the command becomes the browser process and blocks. Detach that case with =&>/dev/null &=, accepting that the confirmation line is discarded — there is no session to confirm into. Don't apply the detach form unconditionally: it suppresses the very output the warm path is verified by.
*** Shell aliases (=ls= → =exa=)
Craig's shell aliases =ls= to =exa=, which prints nothing to non-TTY pipes (e.g. when capturing =ls= output in a Bash tool call). The result looks like the directory is empty when it isn't.
diff --git a/claude-templates/.ai/workflows/startup.org b/claude-templates/.ai/workflows/startup.org
index 1dff1db..2262eea 100644
--- a/claude-templates/.ai/workflows/startup.org
+++ b/claude-templates/.ai/workflows/startup.org
@@ -179,12 +179,14 @@ These calls have no dependencies on each other. Issue them all together in one m
10. =[ -f "$HOME/org/roam/inbox.org" ] && grep -cE '^\*\* ' "$HOME/org/roam/inbox.org" || true= — count items in the roam global inbox (=~/org/roam/inbox.org=), the roam-mode startup nudge. Silent if the roam clone isn't on this machine. Phase C reads the file when the count is non-zero, splits total vs items related to this project, and surfaces the offer (see =inbox.org= roam mode). Read-only; never files at startup.
11. KB surface prep (the read + contribute startup nudges; see =docs/specs/2026-06-16-encourage-kb-contribution-spec.org=). Gated on the agent KB clone. Counts =:agent:= nodes, lists up to 5 whose content matches the current project basename (titles only; a few most-recent nodes as a fallback when nothing matches), and resolves the best-practices node path. Read-only; silent when the clone is absent. Phase C surfaces the relevant titles (consult) and the best-practices link (contribute).
+ The best-practices lookup matches the node's *filename*, not its content. A roam node's slug lives only in its filename, so the earlier content-grep (=rg -l 'agent-kb-best-practices'=) matched nothing and the contribute nudge silently pointed at an empty path in every project, every session, for as long as it shipped. =find= rather than a glob keeps the probe identical under bash and zsh (zsh aborts on an unmatched glob) — the same reason the spec-sort probe below uses =find=.
+
#+begin_src bash
ra="$HOME/org/roam/agents"
if [ -d "$ra" ]; then
proj=$(basename "$PWD")
echo "kb-total: $(rg -l '#\+filetags:.*:agent:' "$ra" 2>/dev/null | wc -l)"
- echo "kb-bestpractices: $(rg -l 'agent-kb-best-practices' "$ra" 2>/dev/null | head -1)"
+ echo "kb-bestpractices: $(find "$ra" -maxdepth 1 -name '*agent-kb-best-practices*.org' -print -quit 2>/dev/null)"
matches=$(rg -il "$proj" "$ra" 2>/dev/null | head -5)
[ -z "$matches" ] && matches=$(\ls -t "$ra"/*.org 2>/dev/null | head -3)
echo "kb-relevant-titles:"